spicrawlspicrawlDocs
Batch

Submit a batch job

Queues many URLs as one asynchronous job and returns `202` with the job object immediately.

Requires scope: batch

POST
/v1/batch

Queues many URLs as one asynchronous job and returns 202 with the job object immediately. Supply either urls (same settings for every URL) or items (one object per URL, with per-item overrides), never both. Every /v1/scrape parameter at the top level (except url) is a job-wide default; an item's own value wins over it, including an explicit false.

Order of work: validate and route every item (a bad item N fails the whole submission with Item N: in detail), reserve the dearest possible cost of the whole job against the monthly credit allowance, write the manifest, enqueue. Nothing is charged at submission (X-Credits-Charged: 0); items are charged individually, only on success, by the worker.

Next step: poll GET /v1/batch/{batchID} (the status_url) until status is completed, failed or cancelled, then page GET /v1/batch/{batchID}/results. Results are readable while the job runs, too.

Not idempotent: there is no Idempotency-Key. Resubmitting the same body creates a second job that is scraped and billed again. If a 202 carries a warning saying items were not all dispatched, do NOT resubmit — the worker's recovery sweep dispatches them.

Limits: request body 1 MiB (1,048,576 bytes); at most 10,000 items per call; job-level parameters at most 65,536 bytes serialised; each item's overrides plus external_id at most 8,192 bytes serialised.

Authorization

bearerAuth
AuthorizationBearer <token>

Authorization: Bearer <key>. Read the key from the SPICRAWL_API_KEY environment variable; never hard-code or log it. spicrawl_test_… keys can never spend live credits. Scopes: scrape, batch, sessions (granted by default), browser and read (granted deliberately). A missing scope is 403 ERR::AUTH::INSUFFICIENT_SCOPE naming the scope.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Body of POST /v1/batch (and of POST /v1/batch/{batchID}/items). Exactly one of urls or items must be non-empty. Top-level BatchScrapeParams fields are job-wide defaults. A top-level url is rejected with 400 — put targets in urls or items[].url. Unknown fields are a 400. Must be ≤ 1 MiB; ≤ 10,000 targets.

Response Body

application/json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

curl -X POST "https://example.com/v1/batch" \  -H "Content-Type: application/json" \  -d '{    "name": "nightly-catalog",    "urls": [      "https://example.com/products/1",      "https://example.com/products/2"    ],    "js_render": true,    "premium_proxy": true,    "proxy_country": "us",    "concurrency": 20  }'
{  "id": "01J9Z6T3W9E21T5TZARVJRVN5C",  "project_id": "01J8X2M4C7Q1H5V9P3R6T8W0YB",  "name": "catalog-2026-09-22",  "status": "running",  "status_url": "/v1/batch/01J9Z6T3W9E21T5TZARVJRVN5C",  "results_url": "/v1/batch/01J9Z6T3W9E21T5TZARVJRVN5C/results",  "params": {    "js_render": true,    "proxy_country": "us",    "credit_budget_micro": 8000000  },  "total_items": 2,  "concurrency": 20,  "priority": 100,  "max_attempts": 3,  "estimated_credits": 8,  "estimated_credits_micro": 8000000,  "progress": {    "total": 2,    "completed": 1,    "succeeded": 1,    "failed": 0,    "cancelled": 0,    "skipped": 0,    "remaining": 1,    "percent_complete": 50,    "credits_charged": 4,    "credits_charged_micro": 4000000,    "bytes": 326000  },  "submitted_at": "2026-09-22T06:41:12Z",  "started_at": "2026-09-22T06:41:13Z",  "results_expire_at": "2026-09-25T06:41:12Z"}