Bulk captures
Up to 1,000 items in one call.
POST /v1/bulk
{
"endpoint": "take",
"options": { "format": "png", "viewport_width": 1280 },
"requests": [
{ "url": "https://example.com/a", "external_identifier": "a" },
{ "url": "https://example.com/b", "external_identifier": "b" }
]
}
options are the shared defaults; each item overrides what it needs.
Two rules govern the response:
- An invalid envelope rejects the whole call. An invalid item rejects only that item — a batch of 900 good URLs is not lost because item 42 has a bad selector.
- The index → result correspondence is preserved. Internal ordering may be optimised; the response order never changes.
Send "execute": false to validate a batch without queueing anything or spending credits.
Every item passes the same plan checks: it consumes one start from the same per-minute bucket as /take, and one credit on success. An item that hits the bucket fails at its own index with concurrency_limit_reached; the rest of the batch continues. Bulk is not a side door around your plan.
Retrying a batch safely
A large batch is the case most likely to time out on the client side, and a timed-out call has already queued — and will bill — whatever it admitted before dying. Send an Idempotency-Key header to make the retry harmless:
curl -X POST https://api.pagecapture.dev/v1/bulk \
-H "X-Access-Key: $PAGECAPTURE_KEY" \
-H "Idempotency-Key: batch-2026-08-02-0001" \
-H "Content-Type: application/json" \
-d @batch.json
Resending with the same key never admits new work. If the original finished, you get its exact response back. If it died partway, you get the request_ids that exist, plus "incomplete": true and unresolved — the count whose fate is unknown. Both replies carry Idempotent-Replay: true.
Keys are scoped to your organization. Without the header, nothing changes: every call is a new batch.