Fetch
Turn a URL into Markdown, HTML or plain text with one request.
POST /v1/fetch opens a URL in a real browser and returns its content as Markdown, HTML or plain text. You do not create or stop a session.
Request
curl -X POST https://api.boxline.dev/v1/fetch \ -H "x-api-key: $BOXLINE_API_KEY" \ -H "content-type: application/json" \ -d '{"url": "https://example.com", "format": "markdown", "links": true}'const page = await bx.fetch("https://example.com", { format: "markdown" });console.log(page.title, page.content);page = bx.fetch("https://example.com", format="markdown")print(page["title"], page["content"])boxline fetch https://example.com # Markdown on stdoutboxline fetch https://example.com --format text # or html| Field | Default | Description |
|---|---|---|
url | required | The page to fetch, an http or https address. |
format | "markdown" | "markdown", "html" or "text". |
links | false | Also return the page’s links, as absolute http(s) addresses (at most 2,000). |
viewport | 1280×720 | { width, height } of the page, from 320×240 to 3840×2160, for sites that change their layout by size. |
It also takes the options every web API shares:
| Field | Default | Description |
|---|---|---|
waitUntil | "load" | When the page counts as loaded: "load", "domcontentloaded", "networkidle" (no network traffic for a moment) or "commit". |
delayMs | 0 | Extra wait after the page loads, up to 10,000 ms. Useful for pages that draw late. |
timeoutMs | 30000 | How long to wait for the page, from 1,000 to 120,000 ms. |
proxy | none | Load the page through a residential, datacenter or your own proxy, e.g. { "type": "residential", "country": "FR" }. The IP changes with every request unless you ask for "ip": "sticky". See Proxies. |
browser | standard | The page’s clock and language, e.g. { "mode": "realistic" } to follow the proxy’s country, or { "locale": "fr-FR", "timezone": "Europe/Paris" }. See Browser mode. |
blockAds | false | Refuse requests to ad and tracker sites while the page loads: faster, with less clutter, and no proxy data spent on them. See Ad and cookie-banner blocking. |
curl -X POST https://api.boxline.dev/v1/fetch \ -H "x-api-key: $BOXLINE_API_KEY" \ -H "content-type: application/json" \ -d '{"url": "https://example.com", "blockAds": true}'const page = await bx.fetch("https://example.com", { blockAds: true });page = bx.fetch("https://example.com", block_ads=True)Response
{ "url": "https://example.com", "finalUrl": "https://example.com/", "status": 200, "title": "Example Domain", "content": "# Example Domain\n\nThis domain is for use in …", "captcha": null, "ms": 1840, "links": ["https://www.iana.org/domains/example"]}finalUrlis the address after redirects.statusis the page’s HTTP status (null when unknown).msis how long it took.linksis only there when you asked for it.captchaisnull, or the kind of CAPTCHA that was waiting for a person on the page (for example"recaptcha"or"cloudflare"). A one-shot request cannot wait for someone to solve it, so the content may be the challenge rather than the page you wanted. See CAPTCHAs.
Choosing a format
- markdown keeps headings, links, images and lists while dropping markup. It is a compact input for a model. Links and images are absolute addresses, resolved against the page (links that start with
#,mailto:andtel:stay as written), so the Markdown still works away from the page. Heading permalinks (the empty#or¶links that documentation sites add after a heading) are left out. - html gives you the markup when you need to parse it yourself.
- text returns just the readable text.
Errors
| Status and code | What it means |
|---|---|
502 page_unreachable | The page could not be loaded. The message names the host and Chrome’s reason, e.g. could not load example.com: ERR_NAME_NOT_RESOLVED. When Chrome’s reason is a generic one, the message adds the real one in words, e.g. (the name does not resolve (DNS)). See why a page did not load. |
504 page_timeout | The page did not finish loading within timeoutMs. Try a longer time or another waitUntil. |
422 not_a_web_page | The address is a PDF. Chrome only displays it, so there is no page text. Download it in a session (with the files API, or curl in its shell) and read it there, for example with pdftotext. The SDKs raise NotAWebPageError and never retry it. |
402 feature_not_in_plan | Your plan does not include this API, or the kind of proxy you asked for. |
429 rate_limited | Too many requests. Wait for the seconds in Retry-After. See Rate limits. |
When a task needs clicks, logins or downloads, use a full session instead. Every field is in the API reference: Fetch a page.
These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.