Skip to main content
Use the Batch API to scrape up to 25,000 URLs asynchronously, or discover pages from a starting URL or sitemap. Choose Markdown or HTML, then poll for completion and download the results.
Already have the URLs? Use this batch scraping guide. To discover pages from a website, follow Crawl Async (25K pages). For a small linked section returned in one response, use Crawl Sync.
Each successful page costs 1 credit, plus any PDF OCR charges. Credits reserved for pages that do not succeed are released when the batch settles. Management calls consume no credits.

Prerequisites

Create an API key at context.dev/signup, copy it from the dashboard, and export it:
Choose cURL or install an SDK for your language. Each example creates its own client. A restricted key needs batches:write to submit or manage jobs; batches:read can read status and results. See API key permissions.

Choose an input

For every mode, set input.data.format to markdown or html. Markdown output supports link and image controls in addition to the common scraping options.

Submit a fixed URL list

Each entry requires a url. Add itemId or meta to match results to your records. Choose a new Idempotency-Key for each new job and reuse it when retrying that job.
The API reserves credits for accepted items at submission and returns 202. Invalid URLs and duplicate pairs of normalized URL and itemId are excluded. The same URL with two different item IDs counts as two items.
sample response
Retries with the same Idempotency-Key and request body return the original batch. Reusing the key with a different body returns 409 IDEMPOTENCY_KEY_CONFLICT. Keys can contain up to 200 characters.
Common options under input.data.options include:Markdown batches also support includeLinks, includeImages, and shortenBase64Images. See Submit a batch for the complete schema.
Use a start_url source to follow links from one page. The starting URL is always included, even when regex does not match it. If the URL has no scheme, Context.dev reads it as HTTPS.
controls is optional. maxUrls defaults to 100, followSubdomains defaults to false, and an omitted maxDepth allows any depth until another control stops discovery.
Use a sitemap source to scrape URLs listed by a domain. The API accepts a bare domain or a full URL and reduces it to the domain.
A sitemap batch scrapes only URLs from the sitemap. It does not follow links from those pages, so sitemap controls support maxUrls and regex, but not maxDepth or followSubdomains.

Poll for completion

Save the id returned by submission, then replace batch_9f2c8a with that ID in the examples:
Poll every 10 to 30 seconds while the status is queued, running, or cancelling. Stop when it becomes completed, cancelled, or failed. A webhook can reduce routine polling, but polling remains the fallback when delivery fails. A crawl can complete below maxUrls when no more eligible pages are reachable. The retrieve response repeats invalid_urls, but not webhook_secret. Store webhook_secret from the submit response immediately; it is returned only once.

Receive a webhook

Use the webhook object in a batch submission to choose a destination and retry policy:
Use retry: {} for the default schedule or retry: { "delays_seconds": [] } to disable automatic retries. Custom schedules accept up to 10 delays, each 1–86,400 seconds, totaling at most 72 hours. Omitting retry preserves one legacy best-effort attempt. The older webhookUrl field also remains a single-attempt option; do not combine it with webhook. Save webhook_secret from the submission response for a custom receiver; it is not included in later retrieve responses. Verify X-Context-Signature before using the payload. It has the form t=<unix>,v1=<hex hmac> and signs {timestamp}.{rawRequestBody} with HMAC-SHA256. Use a constant-time comparison and reject stale timestamps. The monitor verification example uses the same algorithm. After verification, deduplicate the event ID, enqueue work, and return a 2xx promptly. Inspect delivery history and attempts, then replay a retained event after repairing your receiver. Poll batches that remain unresolved in your system; Retrieve Batch is the authoritative status and provides fresh signed result URLs.

Send batch notifications to Slack

Create a Slack or GovSlack incoming webhook for the destination channel and use its URL as webhook.url. Terminal batch events arrive as formatted messages with a source link. Automatic retries and manual replay use the same Slack formatting. Keep the incoming-webhook URL in your secret store. Custom webhook destinations continue receiving the standard batch.completed, batch.failed, or batch.cancelled payloads.

Read the results

Once the batch is terminal, request a page of results:
Successful records have status: "ok" plus http_status, final_url, metadata, and either markdown or html. Failed records have status: "error", error_code, and message. Scrape results echo any submitted itemId and meta.
sample response
A page can close before limit to keep its payload under approximately 8 MB. Continue based on has_more and next_cursor, not the number of records. Replace CURSOR_FROM_PREVIOUS_RESPONSE with the returned cursor, or set NEXT_CURSOR for cURL:
For large result sets, retrieve the batch and download the signed URLs in results.files instead. Each file is gzipped NDJSON. The response includes results.expires_at; retrieve the batch again to obtain fresh links after they expire.

Find previous batches

List batches newest first and combine status, search, and tag filters:
q matches batch IDs, crawl sources, and tags. The tags filter matches batches containing any supplied tag. Continue with next_cursor when has_more is true.

Cancel or delete a batch

Cancellation stops new pages from starting. Pages already in progress finish before the batch reaches cancelled, and unused reserved credits are released.
After a batch reaches completed, cancelled, or failed, you can permanently delete its metadata and stored results:

Handle errors

Batch management has a separate 1,000-unit-per-minute organization limit. A submission uses 50 units; each read, poll, cancellation, or deletion uses 1. See Batch rate limits.

Next steps

Add batch scraping to your app

Open in Cursor

Submit a batch

Full request schema, examples, and responses.

Batch results

Paginated success and error records.

Scrape a webpage

Use synchronous scraping for one page at a time.

Best practices

Authentication, retries, caching, and error handling.