Capture Tasks
A capture task is one page of a capture batch: what was asked, what the page answered, and the screenshot.
Read a capture task
endpoint
GET /api/v1/projects/{project_id}/capture-tasks/{capture_task_id}One capture_task. Minimum key role: Participant. Its id is in the batch's tasks.
The capture_task object
capture_task
{
"object": "capture_task",
"id": "00000000-0000-0000-0000-000000000005",
"capture_batch_id": "00000000-0000-0000-0000-000000000002",
"page": {
"id": "00000000-0000-0000-0000-000000000007",
"path": "/pricing",
"title": "Pricing"
},
"status": "DONE",
"error": null,
"input": {
"url": "https://example.com/pricing",
"viewport": {
"width": 1280,
"height": 800
},
"max_capture_height": 20000,
"mask_selectors": [
".ad"
],
"hide_selectors": [
"#cookie-banner"
],
"unfocus_before_capture": true,
"freeze_animations": true,
"settle_delay_ms": 0
},
"custom_headers_used": [
{
"name": "x-preview-token",
"sent_to_third_parties": false
}
],
"response": {
"http_status": 200,
"page_title": "Pricing – Example"
},
"capture": {
"document": {
"width": 1280,
"height": 3120
},
"captured": {
"width": 1280,
"height": 3120
},
"cropped_width": 0,
"truncated_height": 0,
"fonts_ready": "loaded"
},
"dom_prep": {
"hidden": [
{
"selector": "#cookie-banner",
"count": 1
}
],
"painted": [
{
"selector": ".ad",
"count": 0
}
],
"invalid": [],
"unfocused": true,
"animations": {
"finished": 3,
"cancelled": 1
}
},
"crashed_frames": [],
"renderer": {
"chrome": "155.0.8059.79",
"built_at": "2026-10-26T14:03:12.511Z",
"fonts": {
"sans-serif": [
"Liberation Sans"
]
}
},
"timing": {
"load_ms": 1840
},
"screenshot": {
"url": "https://…",
"expires_at": "2026-11-06T12:00:00.000Z",
"bytes": 482133,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
},
"thumbnail": {
"url": "https://…",
"expires_at": "2026-11-06T12:00:00.000Z",
"bytes": 21004
},
"created_at": "2026-11-06T10:00:00.31+00:00",
"updated_at": "2026-11-06T10:00:09.7+00:00"
}Identity and outcome
| Field | Type | Value |
|---|---|---|
capture_batch_id | uuid string | Its batch. |
page | object | null | The page: id, path, title today. null once the page is deleted. |
status | string | PENDING, RUNNING, DONE or ERROR. |
error | object | null | When the capture failed: code and message — see when a page capture fails. null otherwise. |
A capture that failed because of the page — an error status, a timeout, a redirect away — still has what it reached: response, capture, screenshot and the rest may be filled in.
What was asked
input is the capture as it was set up when it ran — the page's settings may have changed since. See capture config.
| Field | Type | Value |
|---|---|---|
input.url | string | null | The address captured. |
input.viewport | object | null | width and height in pixels: the browser's window. The width is held to the plan's maximum. |
input.max_capture_height | number | null | The tallest capture the plan allows, in pixels; null when the plan sets none. |
input.mask_selectors | string[] | CSS selectors painted over in a solid colour, layout kept. |
input.hide_selectors | string[] | CSS selectors hidden, layout collapsed. |
input.unfocus_before_capture | boolean | null | Whether focus was taken off the page before the shot, so no field shows a caret or ring. |
input.freeze_animations | boolean | null | Whether animations were brought to their end, endless ones removed, before the shot. |
input.settle_delay_ms | number | null | A wait after the page loaded, in milliseconds, from 0 to 5000. |
custom_headers_used | array | The environment's custom HTTP headers sent: their name only, never their value, and sent_to_third_parties, whether they also went to other sites the page loads from. |
What the page answered
| Field | Type | Value |
|---|---|---|
response.http_status | number | null | The page's HTTP status. |
response.page_title | string | null | The page's <title> when it was captured. |
capture | object | null | The sizes, in pixels. null when nothing was captured. |
capture.document | object | width and height of the page itself, measured just before the shot. |
capture.captured | object | width and height of the screenshot. |
capture.cropped_width | number | Pixels of horizontal overflow cut off. 0: nothing lost. |
capture.truncated_height | number | Pixels of page height cut off at the plan's limit. 0: nothing lost. |
capture.fonts_ready | string | null | loaded when the web fonts were ready before the shot; timeout when they were not, and fallback fonts may show. |
dom_prep | object | null | What preparing the page did. null when it did not run. |
dom_prep.hidden | array | Per hide selector: selector, and count, how many elements it matched. 0 is normal on a page without them. |
dom_prep.painted | array | The same for the mask selectors. |
dom_prep.invalid | string[] | Selectors the browser rejected as invalid CSS. They are skipped, the capture goes on. |
dom_prep.unfocused | boolean | null | Whether focus was taken off the page. |
dom_prep.animations | object | null | finished and cancelled: animations brought to their end, and endless ones removed. null when animations were left running. |
crashed_frames | string[] | Addresses of frames from other sites that crashed during the capture. The page is captured all the same, with a grey box where each was — see when an embedded frame crashes. |
renderer | object | null | The browser that drew the page. |
renderer.chrome | string | null | Its Chrome version. |
renderer.built_at | string | null | When that browser image was built. |
renderer.fonts | object | null | Per font family the browser was tested with, the fonts it actually drew with. Two captures drawn with different fonts can differ for that alone. |
timing.load_ms | number | null | How long the page took to load, until its network went quiet, in milliseconds. |
Images
| Field | Type | Value |
|---|---|---|
screenshot | object | null | The full-page PNG. null when there is none. |
screenshot.url | string | null | A signed address to download it from, valid until expires_at. |
screenshot.expires_at | timestamp | null | When url stops working: up to two hours after the call. Trust this date, not a fixed delay. |
screenshot.bytes | number | null | Its size, approximately. |
screenshot.sha256 | string | null | The SHA-256 of the PNG, in hex. Two captures with the same hash are the same image, byte for byte. |
thumbnail | object | null | A small preview of the screenshot: url, expires_at, bytes, as above. |
Download an image while its url is valid, or read the task again for a fresh one: do not store the address. url is null in the rare case the image could not be signed at that moment; read the task again.