{"info":{"description":"Web reading for AI agents: readable text and site maps without a browser, browser rendering when JavaScript is required, and raw HTTP for everything else.","license":{"name":"Commercial API"},"title":"readfetch.com","version":"0.1.0"},"openapi":"3.1.0","paths":{"/healthz":{"get":{"responses":{"200":{"description":"ok"}},"summary":"Liveness check"}},"/v1/batch":{"post":{"description":"Up to 50 URLs in one call and one payment. Results in input order; an undelivered page is not billed and is credited.","requestBody":{"content":{"application/json":{"schema":{"properties":{"accept_language":{"default":null,"type":["string","null"]},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"format":{"default":"markdown","enum":["markdown","text"],"type":"string"},"fresh":{"default":false,"type":"boolean"},"pipeline":{"default":"text","description":"text = HTTP-first; render needs the browser tier.","enum":["text","render"],"type":"string"},"timeout_s":{"default":95,"description":"Total budget for the whole batch in seconds; every item shares it and no item restarts it.","maximum":95,"minimum":1,"type":"number"},"urls":{"description":"URLs to read, deduped before quoting.","items":{"format":"uri","type":"string"},"maxItems":50,"minItems":1,"type":"array"}},"required":["urls"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed_pages":1,"credit":null,"delivered":1,"failed":0,"results":[{"billed":true,"content_sha256":"...","hint":null,"requested_url":"https://example.com","status_code":200,"text":"...","title":"Example Domain","url":"https://example.com/","used_browser":false}],"status":"partial"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Up to 50 URLs in one call and one payment. Results in input order; undelivered pages come back as credit.","tags":["Data"]}},"/v1/crawl":{"post":{"description":"Bounded async crawl with a job id, a page cap quoted up front, and per-page Markdown.","requestBody":{"content":{"application/json":{"schema":{"properties":{"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"exclude":{"items":{"type":"string"},"type":"array"},"include":{"description":"Path prefixes; * suffix wildcard.","items":{"type":"string"},"type":"array"},"max_depth":{"default":2,"maximum":3,"minimum":1,"type":"number"},"max_pages":{"default":20,"maximum":100,"minimum":1,"type":"number"},"url":{"format":"uri","type":"string"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"hint":"GET /v1/crawl/{id} for progress","job_id":"job_ab12","pages_quoted":20,"price_usd":"0.0500","status":"queued"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Bounded async crawl with a job id, a page cap quoted up front, and per-page Markdown.","tags":["Search"]}},"/v1/diff":{"post":{"description":"Stateless change detection: send the hash you hold, get changed/unchanged and a bounded diff. A no-change answer is billable.","requestBody":{"content":{"application/json":{"schema":{"properties":{"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"format":{"default":"text","enum":["text","markdown"],"type":"string"},"previous_content":{"description":"Previous text, for an added/removed diff.","type":["string","null"]},"previous_hash":{"description":"sha256:... from a previous call.","type":["string","null"]},"timeout_s":{"maximum":120,"minimum":1,"type":"number"},"url":{"format":"uri","type":"string"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"added":["New line"],"billed":true,"changed":true,"diff":"@@ -1 +1 @@\n-Old line\n+New line","hash":"sha256:...","hint":null,"removed":["Old line"],"status":"changed","status_code":200,"url":"https://example.com/pricing"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Stateless change detection. Send the hash you hold, get back whether it changed and a bounded diff.","tags":["Data"]}},"/v1/fetch":{"post":{"description":"Send an arbitrary HTTP request (GET, POST, PUT, PATCH, DELETE, HEAD) and return the response with status, headers and body, as text or base64. Intended for APIs, GraphQL, PDFs, byte ranges and large payloads where a browser is not needed.","requestBody":{"content":{"application/json":{"schema":{"properties":{"binary":{"default":false,"title":"Binary","type":"boolean"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Body"},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"egress_fallback":{"description":"Pool to retry through once when the first attempt is refused (bot check, wall, empty extraction, origin 403/429/5xx); must differ from `egress`. Absent keeps one exit for the whole call.","title":"Egress Fallback","type":"string"},"follow_redirects":{"default":true,"title":"Follow Redirects","type":"boolean"},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"title":"Headers"},"json_body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"default":null,"title":"Json Body"},"max_bytes":{"default":10000000,"maximum":50000000,"minimum":1024,"title":"Max Bytes","type":"integer"},"method":{"default":"GET","enum":["GET","POST","PUT","PATCH","DELETE","HEAD"],"title":"Method","type":"string"},"timeout_s":{"default":95,"description":"Total budget for the whole call in seconds, redirect hops included.","maximum":95,"minimum":1,"title":"Timeout S","type":"number"},"url":{"format":"uri","maxLength":2083,"minLength":1,"title":"Url","type":"string"}},"required":["url"],"title":"FetchRequest","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"content_type":"application/json","size":512,"status":"success","status_code":200,"text":"{\"items\": []}","url":"https://api.example.com/items"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Raw HTTP through the same egress. JSON APIs, GraphQL, PDFs, byte ranges - anything that is not a page.","tags":["Infra"]}},"/v1/map":{"post":{"description":"Discover a site's crawlable surface without crawling it: parse robots.txt allow/disallow rules, collect URLs from sitemap.xml and sitemap indexes, find RSS, Atom and JSON feeds, and count internal and external links on the homepage. Use the returned URLs to plan a /v1/scrape or /v1/crawl.","requestBody":{"content":{"application/json":{"schema":{"properties":{"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"egress_fallback":{"description":"Pool to retry through once when the first attempt is refused (bot check, wall, empty extraction, origin 403/429/5xx); must differ from `egress`. Absent keeps one exit for the whole call.","title":"Egress Fallback","type":"string"},"limit":{"default":200,"description":"Maximum number of URLs to return (1-1000).","maximum":1000,"minimum":1,"title":"Limit","type":"integer"},"max_bytes":{"default":5000000,"description":"Abort if any single document exceeds this many bytes.","maximum":20000000,"minimum":1024,"title":"Max Bytes","type":"integer"},"timeout_s":{"default":60,"description":"Total budget for the whole call in seconds; every sitemap fetch and the browser fallback share it. 95 s is the edge ceiling (Cloudflare closes at 100 s).","maximum":95,"minimum":1,"title":"Timeout S","type":"number"},"url":{"description":"Public http(s) URL of the site to map.","format":"uri","maxLength":2083,"minLength":1,"title":"Url","type":"string"}},"required":["url"],"title":"MapRequest","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"feeds":["https://example.com/feed.xml"],"host":"example.com","links":{"external":6,"internal":34},"robots":{"allow":[],"crawl_delay":null,"disallow":["/admin"],"sitemaps":["https://example.com/sitemap.xml"]},"sitemaps":["https://example.com/sitemap.xml"],"status":"success","status_code":200,"total_found":2,"url":"https://example.com","url_count":2,"urls":["https://example.com/","https://example.com/blog/post"]}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Sitemaps, robots rules, feeds and link counts for a whole site, in one call. Plan a crawl before paying for it.","tags":["Search"]}},"/v1/pdf":{"post":{"description":"Documents, not pages: page text plus one Markdown body, priced per document.","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"required":["url"]},{"required":["content_base64"]}],"properties":{"content_base64":{"description":"Inline PDF, up to 20 MB.","type":"string"},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"filename":{"type":"string"},"max_pages":{"default":50,"maximum":200,"minimum":1,"type":"number"},"url":{"description":"PDF URL, fetched through egress.","example":"https://example.com/paper.pdf","format":"uri","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed":true,"content_sha256":"...","hint":null,"markdown":"# Title\n\n...","metadata":{"author":"...","created":"2026-01-04","producer":"..."},"page_count":12,"pages":[{"page":1,"text":"..."}],"source":"https://example.com/report.pdf","status":"success","title":"Annual Report"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Documents, not pages: page text plus one Markdown body, priced per document rather than per page.","tags":["Data"]}},"/v1/probe":{"post":{"description":"Metadata before spending: status, content type, size, title, language and whether a bot wall is waiting. No page body, no browser, always free.","requestBody":{"content":{"application/json":{"schema":{"properties":{"accept_language":{"default":null,"description":"Accept-Language header, e.g. 'de-DE,de;q=0.9'. Defaults to en-US.","type":["string","null"]},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"timeout_s":{"default":10,"description":"Total budget for the whole call in seconds.","maximum":60,"minimum":1,"type":"number"},"url":{"description":"Public http(s) URL to inspect.","format":"uri","maxLength":2083,"minLength":1,"type":"string"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed":false,"bytes":41233,"challenge":false,"content_sha256":"9f2c1b0d4f5a6e7c8b9d0a1f2e3d4c5b6a7f8e9d0c1b2a3f4e5d6c7b8a9f0e1d","content_type":"text/html; charset=utf-8","language":"en","redirected":true,"requested_url":"https://example.com","status":"success","status_code":200,"title":"Example Domain","url":"https://www.example.com/"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Metadata before spending: status, type, title, size, language, whether a bot wall is waiting. No page body.","tags":["Data"]}},"/v1/scrape":{"post":{"description":"JavaScript rendering and web scraping for agents: load a public URL in a real browser session, optionally scroll, wait for selectors, run JS, set headers, cookies or auth, and return Markdown, text or HTML with the page's links.","requestBody":{"content":{"application/json":{"schema":{"$defs":{"Auth":{"description":"Agent-friendly authentication: cookie, bearer token, or basic auth.","properties":{"cookies":{"anyOf":[{"items":{"$ref":"#/$defs/Cookie"},"type":"array"},{"type":"null"}],"default":null,"title":"Cookies"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Password"},"token":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Token"},"type":{"enum":["cookie","bearer","basic"],"title":"Type","type":"string"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Username"}},"required":["type"],"title":"Auth","type":"object"},"Cookie":{"properties":{"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Domain"},"name":{"title":"Name","type":"string"},"path":{"default":"/","title":"Path","type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Url"},"value":{"title":"Value","type":"string"}},"required":["name","value"],"title":"Cookie","type":"object"},"ScrapeOptions":{"description":"Advanced browser/interaction controls (the `advanced` object).","properties":{"cookies":{"anyOf":[{"items":{"$ref":"#/$defs/Cookie"},"type":"array"},{"type":"null"}],"default":null,"title":"Cookies"},"delay_before_return_ms":{"default":0,"maximum":60000,"minimum":0,"title":"Delay Before Return Ms","type":"integer"},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"title":"Headers"},"include_html":{"default":false,"title":"Include Html","type":"boolean"},"include_links":{"default":false,"title":"Include Links","type":"boolean"},"js_code":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"default":null,"title":"Js Code"},"locale":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Browser locale, e.g. 'en-US'. Sets Accept-Language inside the render.","title":"Locale"},"max_scroll_steps":{"anyOf":[{"maximum":200,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"title":"Max Scroll Steps"},"scan_full_page":{"default":false,"title":"Scan Full Page","type":"boolean"},"sticky_session":{"default":false,"description":"Pin one outbound address for the whole call instead of one per connection. A render already runs under one egress session, so the page load never spreads across exits; accepted for compatibility with callers that set it.","title":"Sticky Session","type":"boolean"},"timezone_id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Browser timezone, e.g. 'America/New_York'.","title":"Timezone Id"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"User Agent"},"wait_for":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Wait For"},"wait_for_timeout_ms":{"default":10000,"maximum":120000,"minimum":0,"title":"Wait For Timeout Ms","type":"integer"}},"title":"ScrapeOptions","type":"object"}},"properties":{"advanced":{"anyOf":[{"$ref":"#/$defs/ScrapeOptions"},{"type":"null"}],"default":null},"auth":{"anyOf":[{"$ref":"#/$defs/Auth"},{"type":"null"}],"default":null},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"egress_fallback":{"description":"Pool to retry through once when the first attempt is refused (bot check, wall, empty extraction, origin 403/429/5xx); must differ from `egress`. Absent keeps one exit for the whole call.","title":"Egress Fallback","type":"string"},"format":{"default":"markdown","enum":["markdown","text","html"],"title":"Format","type":"string"},"fresh":{"default":false,"title":"Fresh","type":"boolean"},"mode":{"default":"render","enum":["fast","render","full"],"title":"Mode","type":"string"},"options":{"anyOf":[{"$ref":"#/$defs/ScrapeOptions"},{"type":"null"}],"default":null,"deprecated":true},"url":{"format":"uri","maxLength":2083,"minLength":1,"title":"Url","type":"string"}},"required":["url"],"title":"ScrapeRequest","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed":true,"cache_status":"miss","markdown":"# Pricing\n\n...","status":"success","status_code":200,"title":"Pricing","url":"https://example.com/pricing"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Chromium renders the page, runs interactions, and returns Markdown, text or HTML with its links.","tags":["Data"]}},"/v1/scrape/residential":{"post":{"description":"Identical request and response to /v1/scrape, but the render leaves through a residential address instead of the datacentre. For targets that block by IP reputation (DataDome, PerimeterX, Cloudflare, AWS WAF). One attempt, no retries: residential bandwidth is the cost, and four times the scrape price is what it takes to cover it honestly.","requestBody":{"content":{"application/json":{"schema":{"$defs":{"Auth":{"description":"Agent-friendly authentication: cookie, bearer token, or basic auth.","properties":{"cookies":{"anyOf":[{"items":{"$ref":"#/$defs/Cookie"},"type":"array"},{"type":"null"}],"default":null,"title":"Cookies"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Password"},"token":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Token"},"type":{"enum":["cookie","bearer","basic"],"title":"Type","type":"string"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Username"}},"required":["type"],"title":"Auth","type":"object"},"Cookie":{"properties":{"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Domain"},"name":{"title":"Name","type":"string"},"path":{"default":"/","title":"Path","type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Url"},"value":{"title":"Value","type":"string"}},"required":["name","value"],"title":"Cookie","type":"object"},"ScrapeOptions":{"description":"Advanced browser/interaction controls (the `advanced` object).","properties":{"cookies":{"anyOf":[{"items":{"$ref":"#/$defs/Cookie"},"type":"array"},{"type":"null"}],"default":null,"title":"Cookies"},"delay_before_return_ms":{"default":0,"maximum":60000,"minimum":0,"title":"Delay Before Return Ms","type":"integer"},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"title":"Headers"},"include_html":{"default":false,"title":"Include Html","type":"boolean"},"include_links":{"default":false,"title":"Include Links","type":"boolean"},"js_code":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"default":null,"title":"Js Code"},"locale":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Browser locale, e.g. 'en-US'. Sets Accept-Language inside the render.","title":"Locale"},"max_scroll_steps":{"anyOf":[{"maximum":200,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"title":"Max Scroll Steps"},"scan_full_page":{"default":false,"title":"Scan Full Page","type":"boolean"},"sticky_session":{"default":false,"description":"Pin one outbound address for the whole call instead of one per connection. A render already runs under one egress session, so the page load never spreads across exits; accepted for compatibility with callers that set it.","title":"Sticky Session","type":"boolean"},"timezone_id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Browser timezone, e.g. 'America/New_York'.","title":"Timezone Id"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"User Agent"},"wait_for":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Wait For"},"wait_for_timeout_ms":{"default":10000,"maximum":120000,"minimum":0,"title":"Wait For Timeout Ms","type":"integer"}},"title":"ScrapeOptions","type":"object"}},"properties":{"advanced":{"anyOf":[{"$ref":"#/$defs/ScrapeOptions"},{"type":"null"}],"default":null},"auth":{"anyOf":[{"$ref":"#/$defs/Auth"},{"type":"null"}],"default":null},"format":{"default":"markdown","enum":["markdown","text","html"],"title":"Format","type":"string"},"fresh":{"default":false,"title":"Fresh","type":"boolean"},"mode":{"default":"render","enum":["fast","render","full"],"title":"Mode","type":"string"},"options":{"anyOf":[{"$ref":"#/$defs/ScrapeOptions"},{"type":"null"}],"default":null,"deprecated":true},"url":{"format":"uri","maxLength":2083,"minLength":1,"title":"Url","type":"string"}},"required":["url"],"title":"ScrapeRequest","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed":true,"cache_status":"miss","markdown":"# Pricing\n\n...","status":"success","status_code":200,"title":"Pricing","url":"https://example.com/pricing"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Scrape through a residential address pool, for targets that refuse a datacentre address. Same contract as /v1/scrape, one attempt, priced for the bandwidth.","tags":["Data"]}},"/v1/screenshot":{"post":{"description":"PNG or JPEG of a rendered page: viewport, full page, or one element.","requestBody":{"content":{"application/json":{"schema":{"properties":{"delay_ms":{"maximum":30000,"minimum":0,"type":"number"},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"format":{"default":"png","enum":["png","jpeg"],"type":"string"},"full_page":{"default":true,"type":"boolean"},"height":{"maximum":2160,"minimum":1,"type":"number"},"mode":{"default":"render","enum":["fast","render","full"],"type":"string"},"selector":{"description":"Capture one element.","type":["string","null"]},"url":{"format":"uri","type":"string"},"width":{"maximum":3840,"minimum":1,"type":"number"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed":true,"content_sha256":"...","format":"png","height":800,"hint":null,"image_base64":"iVBORw0KG...","mime":"image/png","size":48213,"status":"success","status_code":200,"url":"https://example.com","width":1280}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"PNG, JPEG or PDF of a rendered page: viewport, full page, or a single element.","tags":["Data"]}},"/v1/search":{"post":{"description":"Web search without a search subscription, returning titles, URLs and snippets.","requestBody":{"content":{"application/json":{"schema":{"properties":{"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"lang":{"description":"e.g. en, de-DE","type":["string","null"]},"limit":{"default":5,"maximum":20,"minimum":1,"type":"number"},"query":{"minLength":1,"type":"string"},"tbs":{"description":"Time range.","enum":["h","d","w","m","y",null],"type":["string","null"]}},"required":["query"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"billed":true,"hint":null,"query":"rust async runtime","results":[{"position":1,"snippet":"...","title":"Tokio","url":"https://tokio.rs/"}],"status":"success"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Web search without a search subscription, returning titles, URLs and snippets.","tags":["Search"]}},"/v1/section":{"post":{"description":"One heading or one selector instead of the whole page. A heading that is not found returns 200, an empty body and the list of headings that do exist.","requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"required":["heading"]},{"required":["selector"]}],"properties":{"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"format":{"default":"markdown","enum":["markdown","text"],"type":"string"},"heading":{"description":"Case-insensitive, whitespace-normalised.","example":"Introduction","type":["string","null"]},"max_chars":{"default":8000,"maximum":20000,"minimum":100,"type":"number"},"mode":{"default":"render","enum":["fast","render"],"type":"string"},"selector":{"description":"CSS selector; up to 20 matches concatenated.","type":["string","null"]},"url":{"format":"uri","type":"string"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"available_headings":["Intro","Authentication","Rate limits"],"billed":true,"chars":1204,"content_sha256":"...","hint":null,"matched":{"kind":"heading","label":"Authentication","level":2},"status":"success","status_code":200,"text":"## Authentication\n\n...","title":"API","url":"https://docs.example.com/api","used_browser":false}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Read one heading or one selector instead of the whole page - ten to a hundred times fewer tokens.","tags":["Data"]}},"/v1/text":{"post":{"description":"Fetch a public URL and return its main readable content as Markdown or plain text, plus title, author, published date and site name. Strips navigation, ads and boilerplate. No JavaScript rendering, so it costs a fraction of a browser scrape; use /v1/scrape when the content only appears after JavaScript runs.","requestBody":{"content":{"application/json":{"schema":{"properties":{"accept_language":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Accept-Language header, e.g. 'de-DE,de;q=0.9'. Defaults to en-US.","title":"Accept Language"},"egress":{"description":"Exit to leave through: `direct` (this service's own datacentre egress) or `residential` (a residential address pool, for targets that refuse datacentre addresses). Omit to use the default route.","title":"Egress","type":"string"},"egress_fallback":{"description":"Pool to retry through once when the first attempt is refused (bot check, wall, empty extraction, origin 403/429/5xx); must differ from `egress`. Absent keeps one exit for the whole call.","title":"Egress Fallback","type":"string"},"format":{"default":"markdown","description":"Output flavour: Markdown keeps headings, lists and tables.","enum":["markdown","text"],"title":"Format","type":"string"},"max_bytes":{"default":5000000,"description":"Abort if the response body exceeds this many bytes.","maximum":20000000,"minimum":1024,"title":"Max Bytes","type":"integer"},"timeout_s":{"default":30,"description":"Total budget for the whole call in seconds: DNS, redirects, the render fallback and any retry share it.","maximum":60,"minimum":1,"title":"Timeout S","type":"number"},"url":{"description":"Public http(s) URL to read.","format":"uri","maxLength":2083,"minLength":1,"title":"Url","type":"string"}},"required":["url"],"title":"TextRequest","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"format":"markdown","metadata":{"author":"A. Writer","date":"2026-04-01","sitename":"Example"},"size":48213,"status":"success","status_code":200,"text":"# Post title\n\nBody as Markdown...","title":"Post title","url":"https://example.com/blog/post"}}},"description":"Delivered. Check `billed`; a call that delivered nothing returns 200 with `billed: false`."},"402":{"description":"Payment required. The body and the PAYMENT-REQUIRED header carry the same amount."}},"summary":"Article text and metadata, boilerplate stripped. No browser by default; falls back to one when a page blocks plain HTTP.","tags":["Data"]}}},"servers":[{"url":"https://readfetch.com"}]}