Check links
Last updated: 2026-10-10
POST /v1/check/links checks 1 to 10 URLs in one call: status, redirect chain, final URL, content_kind, title and content hash for each, under one signed receipt. Price: US$0.005 per batch.
Use it to check the sources in a draft before you publish or hand it on.
Request
{ "urls": ["https://www.iana.org/help/example-domains", "https://www.iana.org/domains/reserved"] }
urls is a list of 1 to 10 items. Each item is an http or https URL string, or an object { "url": "...", "expected_text": "..." } (see expected_text). Each URL is at most 2,048 characters. Every URL is checked before payment; if any one is malformed, blocked or disallowed by robots.txt, the whole request is refused and not charged.
Response
From the free sample (GET /v1/sample/links), shortened:
{
"results": [
{
"url": "https://s2h6qt73jtzlgbgnnfacln2poq.srv.us/v1/sample/page",
"final_url": "https://s2h6qt73jtzlgbgnnfacln2poq.srv.us/v1/sample/page",
"http_status": 200,
"redirects": [],
"content_kind": "real",
"verdict": "ok",
"title": "Regional climate report 2025 (demo page)",
"content_sha256": "0e429607…"
},
{
"url": "https://s2h6qt73jtzlgbgnnfacln2poq.srv.us/v1/sample/missing",
"final_url": "https://s2h6qt73jtzlgbgnnfacln2poq.srv.us/v1/sample/missing",
"http_status": 404,
"redirects": [],
"content_kind": "http_error",
"verdict": "broken",
"title": null,
"content_sha256": "cb699046…"
}
],
"receipt": "eyJhbGciOiJFZERTQSIs…",
"tier": "paid"
}
Link verdict
Each result has a verdict for the link itself, one of:
| verdict | meaning |
|---|---|
ok | The URL resolves and stays on the same address; the page was read, or is a PDF. |
broken | The URL fails: content_kind is http_error (4xx, 5xx, DNS, connection or redirect-loop failure), or it redirects to another site that answers 4xx or 5xx (off_site_error). |
moved | The URL redirects to a different address, and the page was read, or is a PDF, or it is off-site. |
unknown | The page was not read or was blocked (bot wall, JavaScript-only page, paywall, empty, too large, timeout, unsupported type, or disallowed by robots.txt). The link is not claimed to be ok or dead. |
The verdict is per URL and is signed into the receipt. It is not the page verdict: content_kind still says what the page was. A 403 from a bot wall is unknown, not broken.
expected_text
An item may carry expected_text: a words or sentence the page should contain. It is matched on the page text, fuzzy and case-folded, the same match as verify/quote. Each result then has expected_text: null when none was sent or the page was not read, otherwise { match, score, start, end, context, quote_sha256, evidence }, where match is exact, fuzzy or none.
expected_text never changes the verdict. A link can be ok while its expected_text.match is none: the link works but the content is not what you expected. It is 1,000 characters at most, and an empty value is refused with 400.
{ "urls": [{ "url": "https://www.iana.org/help/example-domains", "expected_text": "reserved for use in documentation" }] }
Dead domains
A URL whose host name does not resolve is reported as a result: content_kind http_error, http_status null, and the batch is charged. If no URL in the batch resolves, the call gets 422 host_not_found and is not charged.
PDF links
A live PDF link (status 2xx, content type application/pdf, on the same site as the URL) is reported with content_kind pdf. check/links does not read PDFs, so its title and content_sha256 are null. To read a PDF's text or check a quote in it, use fetch or verify/quote on the full service.
Links that are not read
check/links reads HTML, text and JSON only. Any other link (a PDF, an image, a download) with a 4xx or 5xx status is http_error, so a dead PDF reads as dead. Any link that redirects to another site is off_site, whatever its type, as for an HTML page. If the other site answers with a 4xx or 5xx status, the result also has "off_site_error": true, so a link that moved to a dead page is not missed; otherwise the field is left out. Where archive snapshots are on, a paid call also looks such a link up (the URL you sent) and adds wayback, as for a failed URL. A live link of another type on the same site is unsupported_type.
Charging
If a URL turns out to be disallowed by robots.txt or rate limited after payment (for example after a redirect), the whole batch answers with an error and is not charged. See Payments.
A free-trial call covers at most 5 URLs. A larger batch is not run as a trial: it gets the normal 402 offer, with details.reason trial_too_large, and is not charged.