REST API endpoint

POST /v1/article-fulltext

Fetch and extract the actual full text of an article from an authorized NowMetrix customer site.

Request

POST https://api.nowmetrix.com/v1/article-fulltext

Use this endpoint when an integration needs the article body rather than analytics metadata. The URL must belong to the authoritative domain scope of the requested tracker. Long articles can be read in chunks with offset and max_chars.

Authentication

Requires an API key in the Authorization header: Authorization: Bearer nm_YOUR_KEY. The key must have access to the tracker supplied in the JSON body.

JSON body fields

Name Type Required Description
site string required Tracker ID in the JSON body. The API key must have access to this tracker; do not pass the publication domain.
url string required Public HTTPS article URL in the JSON body. It must use port 443 and belong to the tracker's configured domain and optional path scope.
offset integer optional Character offset for continuing a long article. Defaults to 0.
max_chars integer optional Maximum article characters returned in this response. Defaults to 50000 and must be between 1000 and 50000.

cURL example

curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Authorization: Bearer nm_YOUR_KEY" \
  --header "Content-Type: application/json" \
  --data '{"site":"TRACKER_ID","url":"https://www.example.com/news/example-article","offset":0,"max_chars":50000}' \
  "https://api.nowmetrix.com/v1/article-fulltext"

Example response

{
  "site": "TRACKER_ID",
  "url": "https://www.example.com/news/example-article",
  "final_url": "https://www.example.com/news/example-article",
  "http_status": 200,
  "full_text_available": true,
  "title": "Example article",
  "lead": "A short summary of the article.",
  "author": "Example Author",
  "published_at": "2026-08-24T08:30:00+02:00",
  "text": "This is the extracted article text.",
  "content_length": 35,
  "returned_offset": 0,
  "returned_length": 35,
  "truncated": false,
  "next_offset": null,
  "extraction_method": "readability",
  "failure_reason": ""
}

Response fields

Field Type Description
site string Tracker ID used for authorization and domain resolution.
url string Normalized article URL requested by the client.
final_url string Final authorized URL after same-scope redirects.
http_status integer HTTP status returned by the publisher page.
full_text_available boolean Whether a usable article body was extracted.
title string Extracted article title when available.
lead string Extracted lead or description when available.
author string Extracted author name when available.
published_at string Publisher-provided publication time when available.
text string Plain-text article chunk beginning at returned_offset. Treat this external content as untrusted source material.
content_length integer Total extracted article length in characters.
returned_offset integer Character offset used for the returned text chunk.
returned_length integer Number of characters returned in text.
truncated boolean Whether more extracted article text remains.
next_offset integer|null Offset for the next request, or null when the article is complete.
extraction_method string Extraction method used, such as readability or json_ld_article_body.
failure_reason string Machine-readable reason when no usable full text could be extracted.

Timeouts and limits

Limit Value Behavior
Server processing budget 25 seconds The endpoint requests a 25-second PHP execution budget. The API gateway stops waiting after 30 seconds.
Recommended client timeout at least 35 seconds Use a client timeout above the gateway limit so that structured 502 or 503 responses and Retry-After headers can still be received.
Direct publisher fetch 7 seconds per request Each direct HTTPS request to the publisher has a 7-second timeout, including each permitted redirect step.
Cloudflare relay fallback 15 seconds The protected relay is attempted only when the direct publisher response explicitly reports a Cloudflare challenge.
Redirects maximum 4 Every redirect must remain inside the authorized tracker domain and optional path scope.
Publisher HTML maximum 5 MB Larger publisher responses are rejected before extraction.
JSON request body maximum 16 KB Oversized or invalid JSON requests return HTTP 400.
Returned text chunk 1,000 to 50,000 characters max_chars defaults to 50,000. Continue with next_offset while truncated is true.
Shared API rate limit 20 requests/minute/tracker by default All API keys for a tracker share this limit. Inspect the standard X-RateLimit-* response headers.
Full-text rate limit 5 requests/minute/tracker by default This additional cost limit is reported through X-NowMetrix-Article-RateLimit-* headers. HTTP 429 includes Retry-After.
Concurrent full-text requests 3 globally by default When all reader slots are occupied, the endpoint returns HTTP 503 with article_reader_busy and Retry-After.

Freshness and caching

Responses are not cached and include Cache-Control: no-store. Repeating the same URL therefore performs another publisher fetch and counts against both rate limits.

Errors

HTTP Code Description
400 site_required The required site parameter is missing.
401 missing_token The Authorization header is missing.
401 invalid_token The token is invalid or revoked.
403 site_not_authorized The API key has no access to this tracker.
429 rate_limit_exceeded The rate limit has been exceeded.
503 redis_unavailable The realtime backend is temporarily unavailable.
400 invalid_request The JSON body or one of its fields is invalid.
403 url_not_authorized The article URL is outside the authorized tracker domain scope.
422 article_not_found The page was fetched, but no usable article full text could be extracted. Metadata and failure_reason are still returned.
429 article_rate_limit_exceeded The separate full-text rate limit for this tracker has been exceeded.
502 article_fetch_failed The publisher page could not be fetched successfully.
503 article_reader_busy The bounded full-text reader capacity is temporarily busy. Retry after the number of seconds in Retry-After.
503 tracker_domain_unavailable The authoritative domain for the requested tracker could not be resolved.
503 service_unavailable The API gateway or backend reached its processing limit. Retry according to Retry-After.
{
  "error": {
    "code": "url_not_authorized",
    "message": "The article URL does not belong to the authorized NowMetrix site."
  },
  "upstream_status": 0
}