Skip to main content
Reader exposes a single content-extraction endpoint: POST /v1/read. What you pass in the body determines whether Reader runs a synchronous scrape, a batch job, or a crawl.

Three shapes of input

Everything else (formats, selectors, proxy mode, caching, webhooks) is a modifier on top of one of those three shapes.

Why one endpoint

You learn one contract instead of four. Your code branches on what it sent, not on which URL it called. When you want to swap a batch for a crawl, you change the body; the endpoint, auth, error handling, retry logic, and response envelope all stay the same.

Synchronous scrape

Response (200):
Sync scrape returns immediately: typically under a second for cached or simple pages, a few seconds for heavy ones. Use it when you have one URL and a human (or tight request budget) waiting for the answer.

Async batch or crawl

Response (201):
Use the id to poll GET /v1/jobs/{id}, stream progress with SSE, or subscribe a webhook for completion. See Async jobs.

What Reader decides for you

You tell Reader what to fetch. Reader decides how:
  • How to render the page (full browser with JavaScript execution and stealth evasion).
  • Which proxy mode to use based on your proxyMode setting (see Proxy modes).
  • Whether to serve from cache.
  • How to parallelize a batch.
This is on purpose. These are the decisions that change as the web changes; baking them into your client code means every change to the web is a change to your code. Reader keeps that surface on our side.

Response envelope

Every JSON response from /v1/read follows the same envelope:
Errors use a parallel envelope:
See Errors for the full code catalog.

Next