curl "https://api.pocketutils.com/v1/link-extract?url=https://example.com" \
-H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch(
"https://api.pocketutils.com/v1/link-extract?url=https://example.com",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } },
);
const { data } = await res.json();
{
"success": true,
"data": {
"url": "https://example.com",
"scannedAt": "2026-07-21T09:14:02.000Z",
"totalLinks": 64,
"truncated": false,
"counts": { "total": 64, "internal": 48, "external": 12, "mailto": 3, "tel": 1 },
"links": [
{
"url": "https://example.com/pricing",
"originalHref": "/pricing",
"text": "Pricing",
"rel": null,
"type": "internal",
"scheme": "https"
},
{
"url": "mailto:hello@example.com",
"originalHref": "mailto:hello@example.com",
"text": "hello@example.com",
"rel": null,
"type": "mailto",
"scheme": "mailto"
}
]
}
}
Crawling & Link Extraction
Link Extractor
Extract every link from a page or an entire site, grouped by type, with anchor text and rel.
GET
/
v1
/
link-extract
curl "https://api.pocketutils.com/v1/link-extract?url=https://example.com" \
-H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch(
"https://api.pocketutils.com/v1/link-extract?url=https://example.com",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } },
);
const { data } = await res.json();
{
"success": true,
"data": {
"url": "https://example.com",
"scannedAt": "2026-07-21T09:14:02.000Z",
"totalLinks": 64,
"truncated": false,
"counts": { "total": 64, "internal": 48, "external": 12, "mailto": 3, "tel": 1 },
"links": [
{
"url": "https://example.com/pricing",
"originalHref": "/pricing",
"text": "Pricing",
"rel": null,
"type": "internal",
"scheme": "https"
},
{
"url": "mailto:hello@example.com",
"originalHref": "mailto:hello@example.com",
"text": "hello@example.com",
"rel": null,
"type": "mailto",
"scheme": "mailto"
}
]
}
}
Three endpoints, sharing the Broken Link Checker’s crawl engine but never checking HTTP status — this tool only reports each link’s metadata (anchor text,
In-page anchors (
See the full error reference for the platform-level codes (
rel, type) and counts by type. Use it to audit outbound links, find every mailto:/tel: on a site, or feed a link graph.
1 credit per call (single-page extract or crawl start)
Extract from a single page
GET /v1/link-extract?url=... extracts every link on one page and returns immediately.
Query parameters
string
required
The page to extract links from.
https:// is assumed if the scheme is omitted.Response
object
required
Hide properties
Hide properties
string
required
Echoes the requested URL.
string
required
ISO 8601 timestamp.
integer
required
Same as
counts.total.boolean
required
true if the page had more than 5,000 links.object
required
Show properties
Show properties
#...) and non-HTTP schemes (javascript:, data:, …) are discovered but excluded from these counts.array
required
Show item shape
Show item shape
string
required
Resolved absolute URL (or the raw href for non-HTTP schemes).
string
required
href exactly as authored in the HTML.
string
required
Anchor text.
string
The
rel attribute, e.g. "nofollow noopener".string
required
"internal", "external", "mailto", "tel", "anchor", or "other".string
required
URL scheme without the colon, e.g.
"https", "mailto".curl "https://api.pocketutils.com/v1/link-extract?url=https://example.com" \
-H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch(
"https://api.pocketutils.com/v1/link-extract?url=https://example.com",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } },
);
const { data } = await res.json();
{
"success": true,
"data": {
"url": "https://example.com",
"scannedAt": "2026-07-21T09:14:02.000Z",
"totalLinks": 64,
"truncated": false,
"counts": { "total": 64, "internal": 48, "external": 12, "mailto": 3, "tel": 1 },
"links": [
{
"url": "https://example.com/pricing",
"originalHref": "/pricing",
"text": "Pricing",
"rel": null,
"type": "internal",
"scheme": "https"
},
{
"url": "mailto:hello@example.com",
"originalHref": "mailto:hello@example.com",
"text": "hello@example.com",
"rel": null,
"type": "mailto",
"scheme": "mailto"
}
]
}
}
Extract from an entire site
For more than one page, start an async crawl and poll it — see Async Jobs & Polling for the full pattern, phase list, and crawl limits (250 pages, 6-minute budget).Start the crawl
POST /v1/link-extract/crawl, body { "url": "..." }. Returns 202 immediately:
{ "success": true, "data": { "jobId": "a1b2c3d4-5678-4e9f-9a0b-1c2d3e4f5a6b" } }
Poll the status
GET /v1/link-extract/crawl/:jobId — free and uncached. Returns the standard job envelope, with progress shaped as phase, message, sitemapFound, sitemapUrlCount, pagesScanned, pagesDiscovered, pagesCap, linksFound. Once status is "done", result is a LinkExtractResult (same shape as the single-page response, capped at 3,000 links instead of 5,000), and each link additionally carries:
array
Sample of source pages the link was found on, capped at 25.
integer
Total number of pages the link was found on across the whole crawl.
curl -X POST https://api.pocketutils.com/v1/link-extract/crawl \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
curl https://api.pocketutils.com/v1/link-extract/crawl/a1b2c3d4-5678-4e9f-9a0b-1c2d3e4f5a6b \
-H "Authorization: Bearer YOUR_API_KEY"
Errors
| Status | Cause |
|---|---|
400 | url missing (query parameter for the single-page extract, body field for crawl) |
404 | jobId doesn’t exist or its 30-minute window has expired |
401, 402, 429) that apply to every endpoint.Was this page helpful?