Extract links from a page
Fetch a live web page and list every link on it: URL, anchor text, rel values, internal or external, and how often it appears.
The page is fetched live, as plain HTML without running JavaScript, and the answer usually arrives within a few seconds. For many pages, start a job.
Parameters
Headers
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
Authorization | string | Yes | – | Bearer followed by your API key. See Authentication. |
Query parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Yes | – | A public page. http:// is upgraded to HTTPS and a URL without a scheme gets https://. Credentials, custom ports and private hosts are refused. |
view | string | No | unique | unique: one entry per distinct target, with occurrences. occurrences: one entry per link, in page order. |
type | string | No | all | all, internal (same hostname as the final URL) or external. counts always cover the whole page. |
maxAge | integer | No | 60 | Seconds, 0–3,600. A copy of the page fetched at most this long ago may be reused (cached: true). 0 always fetches. |
wait | integer | No | 60 | Seconds to wait for the page, 1–85. If it is not ready by then, the answer is 202 with resultsUrl. |
Response
| Field | Type | Description |
|---|---|---|
url | string | The URL you sent, after normalising. |
finalUrl | string | The page that answered, after redirects. |
status | integer | The website's HTTP status. |
title | string | null | The page title. |
redirects | array | Each redirect on the way, {url, status}. |
collectedAt | string | When the page was fetched (UTC). |
cached | boolean | true when a copy within maxAge was reused. |
counts | object | links (distinct targets), internal, external and occurrences, for the whole page. |
links[].href | string | The absolute target URL. |
links[].anchor | string | The link text (or the image's alt text). |
links[].internal | boolean | Same hostname as finalUrl. |
links[].rel | string[] | The rel values. |
links[].nofollow, sponsored, ugc | boolean | Whether rel holds each value. |
links[].occurrences | integer | How many times the target appears (with view=unique). |
view | string | The view used. |
jobId | string | The one-page job behind the request. |
Common questions
Why are there no links, or fewer than in my browser?
The page is read as served, without JavaScript. Links that a script adds after loading are not in the HTML. Bot View tells you whether a page needs JavaScript.
How is internal decided?
By hostname: www.example.com and blog.example.com are different hosts. Links to other subdomains count as external.
Errors
| Status | When |
|---|---|
| 202 | The page is not ready within wait. Read it from resultsUrl (see Get results). |
| 400 | url or another parameter is missing or invalid. |
| 401 | No valid API key. |
| 422 | The website answered with an error, timed out, or the page could not be read. The body has the page's status and an error with message, code (such as SOURCE_HTTP_404) and retryable. |
| 429 | The service is busy. Wait for Retry-After. |
| 503 | The service is busy or paused. Retry after Retry-After. |
Limits
No per-key limits. A job holds up to 600 URLs (a single-page request is a one-URL job). When the service is busy you get 429 or 503 with Retry-After.
MCP
On the MCP server, the tool for this is extract_page_links.