Skip to main content
POST
Three endpoints, sharing one link-checking engine: scan one page synchronously, or start a site-wide crawl (via sitemap.xml and internal links) and poll it to completion. Discovered links are resolved and classified by severity. HTTP(S) destinations are checked; other link types receive an informational or diagnostic assessment.
2 credits per call (single-page scan or crawl start)

Scan a single page

POST /v1/broken-links discovers links on one page, assesses up to 80 unique link records, and returns the completed response in the same request.

Body parameters

string
required
The page to scan. https:// is assumed if the scheme is omitted.

Response

object
required

Crawl an entire site

Use the crawl API to discover internal pages and check the unique links found across them. The result includes link outcomes, source pages, page fetch results, and a health score for the assessed links. The base URL is https://api.pocketutils.com. Replace {jobId} with data.jobId from the start response; do not include the braces.

Authentication and credits

Use Authorization: Bearer YOUR_API_KEY or X-API-Key: YOUR_API_KEY on API requests. API-key callers do not need a Turnstile token. Website callers using a session cookie or the anonymous allowance must provide X-Turnstile-Token when starting a crawl. Polling does not require Turnstile. The start request is billed when it returns 202. Polling costs 0 credits, but every poll counts against your requests-per-minute limit. A later background job failure does not automatically refund an accepted start request. See Authentication and Rate Limits & Credits.

Start request

Send Content-Type: application/json and a JSON object with the following field: The request supports only url. Page limits, timeouts, link caps, custom headers, and crawl depth are not configurable through this endpoint. Use the site root for a general audit. A URL under /docs does not restrict the crawl to that path. A successful start returns 202 Accepted with success: true and data.jobId, a UUID string. Save this ID and poll the matching tool’s status endpoint. The response contains no results yet. Each start creates a new job. Repeating the POST creates another job and can incur another charge; reuse the existing job ID to check progress.

Start example

202 Accepted

Get progress and results

GET /v1/broken-links/crawl/{jobId} takes one required path parameter: No request body or query parameters are required. The completed result is returned by this same endpoint; there is no separate result download or pagination endpoint.

Job response fields

Phases

Progress fields

These counters are snapshots. linksChecked includes informational assessments, not just HTTP requests. Do not calculate a stable overall percentage from changing page-discovery counts.
200 OK — checking

Completed result fields

The crawl result differs from the single-page response: it uses totalUniqueLinks, truncatedPages, and truncatedLinks, and adds a pages array. Do not expect totalLinks or truncated in a crawl result.

Summary and status breakdown

summary contains integer fields ok, warnings, broken, info, internal, and external. The four severity counts sum to checkedLinks. internal and external count link types, so their sum may be smaller than checkedLinks when anchors or non-HTTP schemes are present. Every statusBreakdown[] item contains:

Page fields

pages records page fetch outcomes, while links records discovered link destinations. A page can be in pages without appearing as a discovered link in links.
200 OK — completed example
Already-fetched internal pages reuse their page fetch outcome. Other HTTP(S) destinations are checked with HEAD; if the server returns 400, 403, 405, or 501, the checker tries GET. Each direct check has an eight-second timeout. If the GET attempt fails at the transport layer, the original HEAD response is retained. Direct link checks do not follow redirects. They report the initial 3xx response and resolve its Location header into finalUrl when available. Page fetches follow up to five redirects, so a reused page result can report the destination’s HTTP status while redirected is true and finalUrl is the reached page. A redirect target in a direct check is not a guarantee that the target works. Use the returned severity and reason instead of assigning severity from status-code class alone: some 4xx responses are warnings. Bare #fragment anchors are not verified during a site crawl. mailto: and tel: do not validate an email address or telephone number. javascript: links are warnings, malformed hrefs are broken, and other non-HTTP schemes are classified without an HTTP request.

Health score and grade

Only ok, warnings, and broken contribute to the score; info is excluded. Let N = ok + warnings + broken. For nonzero N:
When N is zero, the score is 100. The grade thresholds are: The score and summary cover only the returned, assessed link subset. A high score does not establish that omitted links or unvisited pages are healthy.

How the site is crawled

The crawler looks for sitemap locations in robots.txt and at /sitemap.xml. It expands one level of sitemap indexes, then scans the entry page and follows discovered internal page links breadth-first. A missing sitemap does not prevent crawling. Internal links are classified by hostname, ignoring a leading www.. Other subdomains count as external. External destinations are collected but are not traversed to discover more pages. PDFs, images, archives, and other recognized asset extensions are not traversed as HTML pages. The crawler reads <a href="..."> elements from the fetched HTML. It does not execute page JavaScript, so links added only after client-side rendering may be absent. It does not forward your PocketUtils API key or browser session to the target website. Pages are deduplicated after removing URL fragments and trailing path slashes. Link records are deduplicated by scheme and resolved URL; different query strings or HTTP link fragments can remain separate records. Repeated occurrences on one page do not increase sourceCount. Link metadata represents one discovered occurrence, rather than every variation of its text or rel attribute.

Crawl and result limits

These limits are fixed by the service. The six-minute page budget is not a promise that the whole job finishes within six minutes. The checker assesses at most 1,500 unique link records, with up to 25 concurrent direct link checks. The cap includes anchors and non-HTTP schemes. Links beyond the cap are not represented in links, summary, statusBreakdown, or healthScore. truncatedPages means queued pages remained when traversal stopped, including stops caused by the time budget. truncatedLinks means the assessment cap excluded discovered links. A job can finish with status: done and either flag set; interpret its results as a partial audit.

Retention and polling behavior

Job state is held in memory. Jobs become eligible for removal 30 minutes after their last progress, result, or error update; cleanup runs every five minutes. Reading a job does not refresh retention. A server restart can also lose a job. Store the completed result in your application if you need it later. Poll about every two seconds for a single job, and use a longer interval when polling several jobs or sharing a small request allowance. Phases can change between polls, so you do not need to observe every phase. Stop on done or error. See Async Jobs & Polling for complete JavaScript and Python examples. A known job returns 200 OK even when data.status is error. The envelope’s success: true means the status lookup succeeded; inspect data.status to determine whether the crawl succeeded. result and error are omitted until applicable, rather than sent as null. Request fresh status snapshots and avoid caching them in your client. The current status handlers do not explicitly set Cache-Control: no-store.

Errors

Validation and missing-job errors use a string error. Platform authentication, credit, and rate-limit errors use an error object with code and message. Handle both shapes; see Errors.
400 Bad Request — missing URL
404 Not Found
A fatal background failure is reported by the status endpoint with HTTP 200:
200 OK — failed job
An individual broken destination normally appears in the completed result.links array; it does not fail the whole job. Stop polling on a job error, address its cause, then start a new crawl if needed.