beta
Documentation

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

FieldTypeValue
capture_batch_iduuid stringIts batch.
pageobject | nullThe page: id, path, title today. null once the page is deleted.
statusstringPENDING, RUNNING, DONE or ERROR.
errorobject | nullWhen 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.

FieldTypeValue
input.urlstring | nullThe address captured.
input.viewportobject | nullwidth and height in pixels: the browser's window. The width is held to the plan's maximum.
input.max_capture_heightnumber | nullThe tallest capture the plan allows, in pixels; null when the plan sets none.
input.mask_selectorsstring[]CSS selectors painted over in a solid colour, layout kept.
input.hide_selectorsstring[]CSS selectors hidden, layout collapsed.
input.unfocus_before_captureboolean | nullWhether focus was taken off the page before the shot, so no field shows a caret or ring.
input.freeze_animationsboolean | nullWhether animations were brought to their end, endless ones removed, before the shot.
input.settle_delay_msnumber | nullA wait after the page loaded, in milliseconds, from 0 to 5000.
custom_headers_usedarrayThe 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

FieldTypeValue
response.http_statusnumber | nullThe page's HTTP status.
response.page_titlestring | nullThe page's <title> when it was captured.
captureobject | nullThe sizes, in pixels. null when nothing was captured.
capture.documentobjectwidth and height of the page itself, measured just before the shot.
capture.capturedobjectwidth and height of the screenshot.
capture.cropped_widthnumberPixels of horizontal overflow cut off. 0: nothing lost.
capture.truncated_heightnumberPixels of page height cut off at the plan's limit. 0: nothing lost.
capture.fonts_readystring | nullloaded when the web fonts were ready before the shot; timeout when they were not, and fallback fonts may show.
dom_prepobject | nullWhat preparing the page did. null when it did not run.
dom_prep.hiddenarrayPer hide selector: selector, and count, how many elements it matched. 0 is normal on a page without them.
dom_prep.paintedarrayThe same for the mask selectors.
dom_prep.invalidstring[]Selectors the browser rejected as invalid CSS. They are skipped, the capture goes on.
dom_prep.unfocusedboolean | nullWhether focus was taken off the page.
dom_prep.animationsobject | nullfinished and cancelled: animations brought to their end, and endless ones removed. null when animations were left running.
crashed_framesstring[]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.
rendererobject | nullThe browser that drew the page.
renderer.chromestring | nullIts Chrome version.
renderer.built_atstring | nullWhen that browser image was built.
renderer.fontsobject | nullPer 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_msnumber | nullHow long the page took to load, until its network went quiet, in milliseconds.

Images

FieldTypeValue
screenshotobject | nullThe full-page PNG. null when there is none.
screenshot.urlstring | nullA signed address to download it from, valid until expires_at.
screenshot.expires_attimestamp | nullWhen url stops working: up to two hours after the call. Trust this date, not a fixed delay.
screenshot.bytesnumber | nullIts size, approximately.
screenshot.sha256string | nullThe SHA-256 of the PNG, in hex. Two captures with the same hash are the same image, byte for byte.
thumbnailobject | nullA 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.