Page through a job's finished items (JSONL)
Streams one page of FINISHED items (status succeeded, failed, cancelled or skipped) in `seq` order as JSON Lines: one `BatchResultLine` object per line, each terminated by `\n`, no array, no trailing pagination object.
Requires scope: batch
Streams one page of FINISHED items (status succeeded, failed, cancelled or skipped) in seq order as JSON Lines:
one BatchResultLine object per line, each terminated by \n, no array, no trailing pagination object.
Works while the job is still running (returns what has finished so far). Unfinished items are never listed.
Pagination is in headers: if X-Next-Cursor is present, request again with cursor=<that value> (the Link
header already contains that URL with your limit and status preserved). No X-Next-Cursor means this page
is the last one right now; on a running job, later calls may return more items after the last seq you saw.
A stream that ends early without the header you expected on a full page indicates a dropped connection — retry
the same cursor.
Bodies: result.content is inlined from the job's stitched result file, which exists only after the job is
terminal, so result is absent on a running job. Caps: 524,288 bytes (512 KiB) per item and 2,097,152 bytes
(2 MiB) per page; see BatchResultBody for truncated / omitted / unavailable.
Retention: results are readable until results_expire_at (72 h after submission by default). After that this
endpoint answers 410 ERR::REQUEST::BEYOND_RETENTION even if rows still exist; the job object itself stays
readable via GET /v1/batch/{batchID}.
Authorization
bearerAuth 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
Path Parameters
The job id (26-character ULID as returned). The 32/36-character UUID form of the same id is also accepted. A malformed id and another tenant's id both answer 404.
26 <= length <= 36Query Parameters
Result lines per page. Out-of-range or non-integer values are a 400. If you see omitted bodies, lower this.
1 <= value <= 5000500Opaque token from the previous page's X-Next-Cursor header (hex-encoded). Pass it back verbatim; omit to start from item 0.
^[0-9a-fA-F]+$Return only items with this terminal status (case-insensitive), e.g. failed to list only failures. queued and running are rejected with 400.
Value in
- "succeeded"
- "failed"
- "cancelled"
- "skipped"
Response Body
application/x-ndjson
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/v1/batch/01J9Z6T3W9E21T5TZARVJRVN5C/results""{\"seq\":0,\"url\":\"https://example.com/1\",\"status\":\"succeeded\",\"attempts\":1,\"http_status\":200,\"request_id\":\"01J9Z7A1B2C3D4E5F6G7H8J9KA\",\"credits_micro\":0,\"bytes\":326000,\"duration_ms\":1840,\"result\":{\"content\":\"\\\"<!doctype html><html>…\\\"\",\"bytes\":326002},\"finished_at\":\"2026-09-22T06:41:14Z\"}\n{\"seq\":1,\"external_id\":\"sku-42\",\"url\":\"https://example.com/2\",\"status\":\"failed\",\"attempts\":3,\"credits_micro\":0,\"bytes\":0,\"duration_ms\":15000,\"error\":{\"code\":\"ERR::UPSTREAM::TIMEOUT\",\"retryable\":true},\"finished_at\":\"2026-09-22T06:42:01Z\"}\n"