Skip to documentation

Capturewell API documentation

Reference documentation for every public endpoint, including request fields, responses, errors, and retry guidance.

Download OpenAPI JSON
Base URL
https://api.capturewell.app
Authentication
Bearer cw_…
Output formats
pngjpegwebpavif
On this page

Overview

API reference formats

Read the API reference on this page, or use the OpenAPI JSON endpoint with code generators and other development tools. Both cover 32 HTTP method/path operations across 14 paths, including PUT and PATCH as separate operations where Laravel accepts both.

API keys

Authenticate requests with a revocable API key beginning with cw_.

Asynchronous captures

Queue long-running captures, poll their status, then use the signed result URL.

Retry behavior

Error codes and response headers explain whether and when to retry a request.

Authentication

Send the key as a Bearer token.

Use Authorization: Bearer $CAPTUREWELL_API_KEY and request JSON with Accept: application/json. Missing, malformed, revoked, or unknown keys return 401 with error.code = unauthenticated.

First request

Capture a public page.

JSON writes require Content-Type: application/json. Watermark uploads use multipart form data. The response includes dimensions, credit use, expiry, and a temporary signed URL when the capture completes.

curl -X POST "https://api.capturewell.app/v1/screenshots" \
  -H "Authorization: Bearer $CAPTUREWELL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com",
  "format": "png",
  "preset": "desktop",
  "full_page": true
}'

Capture lifecycle

Poll until completed or failed.

queued
processing
completed
failed

Queued and processing are non-terminal. Completed and failed are terminal. Retention is configuration-dependent, so trust each response's expires_at instead of assuming a duration. Signed file URLs also expire; fetch or copy the result while valid.

Pagination and identifiers

Follow page links and preserve identifier types.

One-indexed result page. Collections contain 20 records per page. Collection responses place records in data, alongside page numbers, totals, and previous and next page URLs. The canonical page size is 20; follow the returned URLs instead of rebuilding them.

Identifier types by API resource
Resource Path parameter Type Example
Capturescapturestring01J00000000000000000000000
Recipesrecipestring01J00000000000000000000001
Watermarkswatermarkstring01J00000000000000000000002
Templatestemplateinteger · int6442
Schedulesscheduleinteger · int6484

Recipe-assisted captures

Recipe actions and restrictions

An owned recipe can dismiss or accept a banner, activate eligible buttons, tabs, and disclosures, hover eligible controls, hide a classified overlay or widget, scroll 1–2,000px or to a named heading or region, press Escape, wait briefly, and verify the requested state after each action.

Recipes cannot type or fill, submit forms, follow links, download or access files, open new tabs or windows, press arbitrary keys, use selectors or XPath, execute JavaScript, click coordinates, or navigate directly or across hosts.

The configured AI provider receives only bounded accessible names, nearby headings and context, visible target text, semantic state, and aggregate effects. It never receives screenshots, raw HTML, cookies, headers, form or input values, URL query strings, or account IDs; response storage remains disabled.

Errors and retries

Read the status and stable error code together.

Status Meaning Retry guidance
401 API key is missing or invalid. Fix credentials before retrying.
403 / 404 Authorization or ownership isolation. Do not retry without correcting ownership or access.
409 / 422 State conflict or validation failure. Change the request using the response details.
429 Either the 60/minute throttle or quota exhaustion. Use rate-limit headers for throttling; add credits for quota_exceeded.
503 Renderer or feature is temporarily unavailable. Back off. Do not blindly replay screenshot creation: it may already have consumed credits.

API reference

All 32 operations.

Filter by method, path, summary, operation ID, or resource. Every result retains a stable deep link.

Showing 32 of 32 operations

Resource

Screenshots

Create, poll, list, delete, and unlock retained screenshots.

get/v1/screenshots

List screenshots

Returns the authenticated account's captures newest first, 20 per page. A recognized status filters the collection. An unknown status is currently ignored and returns the unfiltered collection.

operationId: listScreenshots

Parameters

Name Location Type Description
page queryintegerOne-indexed result page. Collections contain 20 records per page.
status querystringOptional capture status filter. An unknown value is silently ignored rather than rejected.

Responses

200Paginated captures.

application/json

List screenshots 200 response fields
FieldType Requirement Description
current_pageintegerRequired
first_page_urlstringRequiredformat: uri
frominteger | nullRequired
last_pageintegerRequired
last_page_urlstringRequiredformat: uri
linksarray<PaginatorLink>Required
next_page_urlstring | nullRequiredformat: uri
pathstringRequiredformat: uri
per_pageintegerRequired
prev_page_urlstring | nullRequiredformat: uri
tointeger | nullRequired
totalintegerRequired
dataarray<Capture>Required
{
  "current_page": 1,
  "first_page_url": "https://api.example.com/v1/screenshots?page=1",
  "from": null,
  "last_page": 1,
  "last_page_url": "https://api.example.com/v1/screenshots?page=1",
  "links": [],
  "next_page_url": null,
  "path": "https://api.example.com/v1/screenshots",
  "per_page": 20,
  "prev_page_url": null,
  "to": null,
  "total": 0,
  "data": []
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

List screenshots 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
List screenshots 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

List screenshots 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
post/v1/screenshots

Create a screenshot synchronously

Creates and renders a screenshot before responding. A standard viewport capture starts at one credit; full-page mode starts at two, higher density tiers add credits, and configured recipe or watermark features may add credits. Recipe-assisted captures are async-only. This operation has no idempotency key, so do not blindly replay it after an ambiguous network failure.

operationId: createScreenshot

Request body

application/json required

Create a screenshot synchronously request fields
FieldType Requirement Description
urlstringRequiredRequired public HTTP or HTTPS URL. Private, loopback, link-local, and reserved targets are rejected.format: uri · length: 0–2048
formatpng | jpeg | webp | avifOptionalOutput format. PNG, JPEG, WebP, and AVIF are supported with or without required Capturewell branding.default: "png"
qualityintegerOptionalJPEG, WebP, or AVIF quality. Non-PNG output defaults to 82. PNG accepts this field but normalizes it to null.range: 1–100
full_pagebooleanOptionalCapture the complete document height.default: false
presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphOptionalNamed viewport preset. The preset continues to supply mobile behavior and default density when viewport dimensions are overridden.default: "desktop"
viewportRequestedViewportOptional
viewport.widthintegerOptionalrange: 320–3840
viewport.heightintegerOptionalrange: 240–2160
device_scale_factornumberOptionalPixel density. Defaults to the selected preset.range: 1–3
delay_msintegerOptionalAdditional delay after page readiness.default: 0 · range: 0–10000
timeout_msintegerOptionalRenderer navigation timeout.default: 30000 · range: 1000–60000
wait_untilload | domcontentloaded | networkidle0 | networkidle2OptionalBrowser readiness event.default: "networkidle2"
wait_for_selectorstring | nullOptionalOptional CSS selector to await before capture.default: null · length: 0–500
dark_modebooleanOptionalPrefer the dark color scheme.default: false
reduced_motionbooleanOptionalPrefer reduced motion while rendering.default: true
remove_brandingbooleanOptionalRequest clean output at creation time. The configured Capturewell watermark-removal cost is included when required branding is active.default: false
watermark_idstring | nullOptionalOwned watermark public ULID. A non-null value is allowed only when remove_branding is true and watermarking is enabled.
recipe_idstring | nullOptionalOwned active recipe public ULID. Recipe capture must be enabled and the asynchronous screenshot endpoint must be used.
{
  "url": "https://example.com",
  "format": "png",
  "preset": "desktop",
  "full_page": true
}

Responses

201The screenshot completed. Signed image and download URLs remain valid until expires_at; clients should trust that field rather than assume a fixed retention duration.

application/json

Create a screenshot synchronously 201 response fields
FieldType Requirement Description
idstringRequired
statusqueued | processing | completed | failedRequired
sourceapi | dashboard | template | scheduleRequired
target_urlstringRequiredformat: uri
optionsCaptureOptionsRequired
options.urlstringRequiredformat: uri
options.formatpng | jpeg | webp | avifRequired
options.qualityinteger | nullRequiredrange: 1–100
options.full_pagebooleanRequired
options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
options.viewportCaptureViewportRequired
options.delay_msintegerRequired
options.timeout_msintegerRequired
options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
options.wait_for_selectorstring | nullRequired
options.dark_modebooleanRequired
options.reduced_motionbooleanRequired
options.remove_brandingbooleanRequired
options.watermarkCustomWatermarkSnapshotOptional
image_urlstring | nullRequiredSigned inline image URL while a completed file remains retained.format: uri
download_urlstring | nullRequiredSigned attachment URL while a completed file remains retained.format: uri
expires_atstring | nullRequiredConfigured retention expiry. The usual default is 24 hours, but clients must trust this timestamp.format: date-time
credits_usedintegerRequiredrange: 0–∞
watermarkedbooleanRequiredWhether the separate Capturewell watermark is currently present.
watermark_removalWatermarkRemovalRequired
watermark_removal.eligiblebooleanRequired
watermark_removal.creditsintegerRequiredrange: 0–∞
watermark_removal.removed_atstring | nullRequiredformat: date-time
recipeCaptureRecipeSummary | nullRequired
created_atstring | nullRequiredformat: date-time
metadataCaptureMetadata | nullRequired
errorCaptureStoredError | nullRequired
{
  "id": "01J00000000000000000000000",
  "status": "completed",
  "source": "api",
  "target_url": "https://example.com",
  "options": {
    "url": "https://example.com",
    "format": "png",
    "quality": null,
    "full_page": false,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "image_url": "https://example.com/captures/01J00000000000000000000000/file?expires=1784203200&signature=fake",
  "download_url": "https://example.com/captures/01J00000000000000000000000/download?expires=1784203200&signature=fake",
  "expires_at": "2026-07-17T12:00:00+00:00",
  "credits_used": 1,
  "watermarked": true,
  "watermark_removal": {
    "eligible": true,
    "credits": 1,
    "removed_at": null
  },
  "recipe": null,
  "created_at": "2026-07-16T12:00:00+00:00",
  "metadata": {
    "width": 1440,
    "height": 900,
    "format": "png",
    "bytes": 128000,
    "duration_ms": 840
  },
  "error": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Create a screenshot synchronously 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
422Validation failed, a synchronous recipe was rejected, or the renderer returned a non-retryable failure.

application/json

{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429Either the request rate limit was exceeded or the account lacks enough credits. A quota_exceeded response does not include Retry-After and is not rescued synchronously by auto recharge; retry only after the balance has actually increased.
Create a screenshot synchronously 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger37Requests remaining in the current window.
Retry-Afterinteger42Present only when the request limiter, rather than the credit quota, caused the response.
X-RateLimit-Resetinteger1784203242Present when the request limiter supplies a reset timestamp.

application/json

{
  "message": "Too Many Attempts."
}
503The synchronous renderer failed with a retryable error. Retry only when error.retryable is true, bearing in mind that screenshot creation has no idempotency key.

application/json

Create a screenshot synchronously 503 response fields
FieldType Requirement Description
idstringRequired
statusstringRequired
errorvalueRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanRequiredWhen present, retry automatically only when true.
{
  "id": "01J00000000000000000000000",
  "status": "failed",
  "error": {
    "code": "renderer_unavailable",
    "message": "The renderer is currently unavailable.",
    "retryable": true
  }
}
post/v1/screenshots/async

Queue a screenshot

Creates a queued capture and returns immediately. Poll the capture with exponential backoff until status is completed or failed. Queued and processing are non-terminal; completed and failed are terminal. Capturewell does not provide a completion webhook.

operationId: createScreenshotAsync

Request body

application/json required

Queue a screenshot request fields
FieldType Requirement Description
urlstringRequiredRequired public HTTP or HTTPS URL. Private, loopback, link-local, and reserved targets are rejected.format: uri · length: 0–2048
formatpng | jpeg | webp | avifOptionalOutput format. PNG, JPEG, WebP, and AVIF are supported with or without required Capturewell branding.default: "png"
qualityintegerOptionalJPEG, WebP, or AVIF quality. Non-PNG output defaults to 82. PNG accepts this field but normalizes it to null.range: 1–100
full_pagebooleanOptionalCapture the complete document height.default: false
presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphOptionalNamed viewport preset. The preset continues to supply mobile behavior and default density when viewport dimensions are overridden.default: "desktop"
viewportRequestedViewportOptional
viewport.widthintegerOptionalrange: 320–3840
viewport.heightintegerOptionalrange: 240–2160
device_scale_factornumberOptionalPixel density. Defaults to the selected preset.range: 1–3
delay_msintegerOptionalAdditional delay after page readiness.default: 0 · range: 0–10000
timeout_msintegerOptionalRenderer navigation timeout.default: 30000 · range: 1000–60000
wait_untilload | domcontentloaded | networkidle0 | networkidle2OptionalBrowser readiness event.default: "networkidle2"
wait_for_selectorstring | nullOptionalOptional CSS selector to await before capture.default: null · length: 0–500
dark_modebooleanOptionalPrefer the dark color scheme.default: false
reduced_motionbooleanOptionalPrefer reduced motion while rendering.default: true
remove_brandingbooleanOptionalRequest clean output at creation time. The configured Capturewell watermark-removal cost is included when required branding is active.default: false
watermark_idstring | nullOptionalOwned watermark public ULID. A non-null value is allowed only when remove_branding is true and watermarking is enabled.
recipe_idstring | nullOptionalOwned active recipe public ULID. Recipe capture must be enabled and the asynchronous screenshot endpoint must be used.
{
  "url": "https://example.com",
  "format": "webp",
  "preset": "desktop",
  "recipe_id": "01J00000000000000000000001"
}

Responses

202The screenshot was queued.

application/json

Queue a screenshot 202 response fields
FieldType Requirement Description
idstringRequired
statusqueued | processing | completed | failedRequired
sourceapi | dashboard | template | scheduleRequired
target_urlstringRequiredformat: uri
optionsCaptureOptionsRequired
options.urlstringRequiredformat: uri
options.formatpng | jpeg | webp | avifRequired
options.qualityinteger | nullRequiredrange: 1–100
options.full_pagebooleanRequired
options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
options.viewportCaptureViewportRequired
options.delay_msintegerRequired
options.timeout_msintegerRequired
options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
options.wait_for_selectorstring | nullRequired
options.dark_modebooleanRequired
options.reduced_motionbooleanRequired
options.remove_brandingbooleanRequired
options.watermarkCustomWatermarkSnapshotOptional
image_urlstring | nullRequiredSigned inline image URL while a completed file remains retained.format: uri
download_urlstring | nullRequiredSigned attachment URL while a completed file remains retained.format: uri
expires_atstring | nullRequiredConfigured retention expiry. The usual default is 24 hours, but clients must trust this timestamp.format: date-time
credits_usedintegerRequiredrange: 0–∞
watermarkedbooleanRequiredWhether the separate Capturewell watermark is currently present.
watermark_removalWatermarkRemovalRequired
watermark_removal.eligiblebooleanRequired
watermark_removal.creditsintegerRequiredrange: 0–∞
watermark_removal.removed_atstring | nullRequiredformat: date-time
recipeCaptureRecipeSummary | nullRequired
created_atstring | nullRequiredformat: date-time
metadataCaptureMetadata | nullRequired
errorCaptureStoredError | nullRequired
{
  "id": "01J00000000000000000000000",
  "status": "completed",
  "source": "api",
  "target_url": "https://example.com",
  "options": {
    "url": "https://example.com",
    "format": "png",
    "quality": null,
    "full_page": false,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "image_url": "https://example.com/captures/01J00000000000000000000000/file?expires=1784203200&signature=fake",
  "download_url": "https://example.com/captures/01J00000000000000000000000/download?expires=1784203200&signature=fake",
  "expires_at": "2026-07-17T12:00:00+00:00",
  "credits_used": 1,
  "watermarked": true,
  "watermark_removal": {
    "eligible": true,
    "credits": 1,
    "removed_at": null
  },
  "recipe": null,
  "created_at": "2026-07-16T12:00:00+00:00",
  "metadata": {
    "width": 1440,
    "height": 900,
    "format": "png",
    "bytes": 128000,
    "duration_ms": 840
  },
  "error": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Queue a screenshot 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Queue a screenshot 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429Either the request rate limit was exceeded or the account lacks enough credits. A quota_exceeded response does not include Retry-After and is not rescued synchronously by auto recharge; retry only after the balance has actually increased.
Queue a screenshot 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger37Requests remaining in the current window.
Retry-Afterinteger42Present only when the request limiter, rather than the credit quota, caused the response.
X-RateLimit-Resetinteger1784203242Present when the request limiter supplies a reset timestamp.

application/json

{
  "message": "Too Many Attempts."
}
get/v1/screenshots/{capture}

Get a screenshot

Returns one account-owned capture. Completed, unexpired captures with retained files include signed image and download URLs. Other states and expired captures return null URLs. A capture owned by another account is indistinguishable from a missing capture.

operationId: getScreenshot

Parameters

Name Location Type Description
capture *pathstringCapture string identifier.

Responses

200Capture details.

application/json

Get a screenshot 200 response fields
FieldType Requirement Description
idstringRequired
statusqueued | processing | completed | failedRequired
sourceapi | dashboard | template | scheduleRequired
target_urlstringRequiredformat: uri
optionsCaptureOptionsRequired
options.urlstringRequiredformat: uri
options.formatpng | jpeg | webp | avifRequired
options.qualityinteger | nullRequiredrange: 1–100
options.full_pagebooleanRequired
options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
options.viewportCaptureViewportRequired
options.delay_msintegerRequired
options.timeout_msintegerRequired
options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
options.wait_for_selectorstring | nullRequired
options.dark_modebooleanRequired
options.reduced_motionbooleanRequired
options.remove_brandingbooleanRequired
options.watermarkCustomWatermarkSnapshotOptional
image_urlstring | nullRequiredSigned inline image URL while a completed file remains retained.format: uri
download_urlstring | nullRequiredSigned attachment URL while a completed file remains retained.format: uri
expires_atstring | nullRequiredConfigured retention expiry. The usual default is 24 hours, but clients must trust this timestamp.format: date-time
credits_usedintegerRequiredrange: 0–∞
watermarkedbooleanRequiredWhether the separate Capturewell watermark is currently present.
watermark_removalWatermarkRemovalRequired
watermark_removal.eligiblebooleanRequired
watermark_removal.creditsintegerRequiredrange: 0–∞
watermark_removal.removed_atstring | nullRequiredformat: date-time
recipeCaptureRecipeSummary | nullRequired
created_atstring | nullRequiredformat: date-time
metadataCaptureMetadata | nullRequired
errorCaptureStoredError | nullRequired
{
  "id": "01J00000000000000000000000",
  "status": "completed",
  "source": "api",
  "target_url": "https://example.com",
  "options": {
    "url": "https://example.com",
    "format": "png",
    "quality": null,
    "full_page": false,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "image_url": "https://example.com/captures/01J00000000000000000000000/file?expires=1784203200&signature=fake",
  "download_url": "https://example.com/captures/01J00000000000000000000000/download?expires=1784203200&signature=fake",
  "expires_at": "2026-07-17T12:00:00+00:00",
  "credits_used": 1,
  "watermarked": true,
  "watermark_removal": {
    "eligible": true,
    "credits": 1,
    "removed_at": null
  },
  "recipe": null,
  "created_at": "2026-07-16T12:00:00+00:00",
  "metadata": {
    "width": 1440,
    "height": 900,
    "format": "png",
    "bytes": 128000,
    "duration_ms": 840
  },
  "error": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Get a screenshot 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Get a screenshot 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Get a screenshot 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Get a screenshot 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
delete/v1/screenshots/{capture}

Delete a screenshot

Cancels a queued capture or deletes a completed or failed capture and its retained files. Processing captures cannot be deleted. Historical credit usage remains. Retry a storage cleanup failure only when error.retryable is true.

operationId: deleteScreenshot

Parameters

Name Location Type Description
capture *pathstringCapture string identifier.

Responses

204The capture was deleted. The response has no body.
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Delete a screenshot 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Delete a screenshot 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
409The capture is processing and cannot be deleted.

application/json

Delete a screenshot 409 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "capture_not_deletable",
    "message": "This capture cannot be deleted while it is processing."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Delete a screenshot 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Delete a screenshot 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
503Retained capture storage could not be cleaned up. This response is explicitly retryable.

application/json

Delete a screenshot 503 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "capture_storage_cleanup_failed",
    "message": "Capture storage cleanup failed.",
    "retryable": true
  }
}
post/v1/screenshots/{capture}/remove-watermark

Unlock the clean original

Permanently switches an eligible retained capture from its Capturewell-branded file to the clean original without re-rendering or extending expiry. Repeating a successful unlock is idempotent and costs no additional credits.

operationId: removeScreenshotWatermark

Parameters

Name Location Type Description
capture *pathstringCapture string identifier.

Responses

200The current capture details. watermarked is false after a successful unlock.

application/json

Unlock the clean original 200 response fields
FieldType Requirement Description
idstringRequired
statusqueued | processing | completed | failedRequired
sourceapi | dashboard | template | scheduleRequired
target_urlstringRequiredformat: uri
optionsCaptureOptionsRequired
options.urlstringRequiredformat: uri
options.formatpng | jpeg | webp | avifRequired
options.qualityinteger | nullRequiredrange: 1–100
options.full_pagebooleanRequired
options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
options.viewportCaptureViewportRequired
options.delay_msintegerRequired
options.timeout_msintegerRequired
options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
options.wait_for_selectorstring | nullRequired
options.dark_modebooleanRequired
options.reduced_motionbooleanRequired
options.remove_brandingbooleanRequired
options.watermarkCustomWatermarkSnapshotOptional
image_urlstring | nullRequiredSigned inline image URL while a completed file remains retained.format: uri
download_urlstring | nullRequiredSigned attachment URL while a completed file remains retained.format: uri
expires_atstring | nullRequiredConfigured retention expiry. The usual default is 24 hours, but clients must trust this timestamp.format: date-time
credits_usedintegerRequiredrange: 0–∞
watermarkedbooleanRequiredWhether the separate Capturewell watermark is currently present.
watermark_removalWatermarkRemovalRequired
watermark_removal.eligiblebooleanRequired
watermark_removal.creditsintegerRequiredrange: 0–∞
watermark_removal.removed_atstring | nullRequiredformat: date-time
recipeCaptureRecipeSummary | nullRequired
created_atstring | nullRequiredformat: date-time
metadataCaptureMetadata | nullRequired
errorCaptureStoredError | nullRequired
{
  "id": "01J00000000000000000000000",
  "status": "completed",
  "source": "api",
  "target_url": "https://example.com",
  "options": {
    "url": "https://example.com",
    "format": "png",
    "quality": null,
    "full_page": false,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "image_url": "https://example.com/captures/01J00000000000000000000000/file?expires=1784203200&signature=fake",
  "download_url": "https://example.com/captures/01J00000000000000000000000/download?expires=1784203200&signature=fake",
  "expires_at": "2026-07-17T12:00:00+00:00",
  "credits_used": 1,
  "watermarked": true,
  "watermark_removal": {
    "eligible": true,
    "credits": 1,
    "removed_at": null
  },
  "recipe": null,
  "created_at": "2026-07-16T12:00:00+00:00",
  "metadata": {
    "width": 1440,
    "height": 900,
    "format": "png",
    "bytes": 128000,
    "duration_ms": 840
  },
  "error": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Unlock the clean original 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Unlock the clean original 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
409The clean original cannot be unlocked because the capture is incomplete, expired, legacy, already lacks an eligible original, or no retained original remains.

application/json

Unlock the clean original 409 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "capture_watermark_not_removable",
    "message": "This capture does not have an eligible retained clean original."
  }
}
429Either the request rate limit was exceeded or the account lacks enough credits. A quota_exceeded response does not include Retry-After and is not rescued synchronously by auto recharge; retry only after the balance has actually increased.
Unlock the clean original 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger37Requests remaining in the current window.
Retry-Afterinteger42Present only when the request limiter, rather than the credit quota, caused the response.
X-RateLimit-Resetinteger1784203242Present when the request limiter supplies a reset timestamp.

application/json

{
  "message": "Too Many Attempts."
}

Resource

Recipes

Manage account-owned natural-language browser-action recipes.

get/v1/recipes

List recipes

Returns the authenticated account's active recipes ordered by most recently updated, 20 per page.

operationId: listRecipes

Parameters

Name Location Type Description
page queryintegerOne-indexed result page. Collections contain 20 records per page.

Responses

200Paginated recipes.

application/json

List recipes 200 response fields
FieldType Requirement Description
current_pageintegerRequired
first_page_urlstringRequiredformat: uri
frominteger | nullRequired
last_pageintegerRequired
last_page_urlstringRequiredformat: uri
linksarray<PaginatorLink>Required
next_page_urlstring | nullRequiredformat: uri
pathstringRequiredformat: uri
per_pageintegerRequired
prev_page_urlstring | nullRequiredformat: uri
tointeger | nullRequired
totalintegerRequired
dataarray<Recipe>Required
{
  "current_page": 1,
  "first_page_url": "https://api.example.com/v1/recipes?page=1",
  "from": null,
  "last_page": 1,
  "last_page_url": "https://api.example.com/v1/recipes?page=1",
  "links": [],
  "next_page_url": null,
  "path": "https://api.example.com/v1/recipes",
  "per_page": 20,
  "prev_page_url": null,
  "to": null,
  "total": 0,
  "data": []
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

List recipes 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
List recipes 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

List recipes 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
post/v1/recipes

Create a recipe

Creates an account-owned natural-language recipe. Recipe-assisted screenshots must use the asynchronous screenshot endpoint and may be subject to a feature gate.

operationId: createRecipe

Request body

application/json required

Create a recipe request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
instructionsstringRequiredlength: 0–2000
{
  "name": "Dismiss cookie banner",
  "instructions": "Accept the cookie banner, then finish."
}

Responses

201The recipe was created.

application/json

Create a recipe 201 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
instructionsstringRequired
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000001",
  "name": "Dismiss cookie banner",
  "instructions": "Accept the cookie banner, then finish.",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Create a recipe 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Create a recipe 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Create a recipe 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Create a recipe 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
get/v1/recipes/{recipe}

Get a recipe

Returns one account-owned recipe. Recipes owned by other accounts return 404.

operationId: getRecipe

Parameters

Name Location Type Description
recipe *pathstringRecipe public ULID.

Responses

200Recipe details.

application/json

Get a recipe 200 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
instructionsstringRequired
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000001",
  "name": "Dismiss cookie banner",
  "instructions": "Accept the cookie banner, then finish.",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Get a recipe 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Get a recipe 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Get a recipe 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Get a recipe 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
put/v1/recipes/{recipe}

Replace a recipe

Replaces the writable recipe fields. Both name and instructions are required. Updating a recipe owned by another account currently returns 403, while an unknown identifier returns 404.

operationId: replaceRecipe

Parameters

Name Location Type Description
recipe *pathstringRecipe public ULID.

Request body

application/json required

Replace a recipe request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
instructionsstringRequiredlength: 0–2000
{
  "name": "Open pricing details",
  "instructions": "Open the annual pricing disclosure, then finish."
}

Responses

200The updated recipe.

application/json

Replace a recipe 200 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
instructionsstringRequired
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000001",
  "name": "Dismiss cookie banner",
  "instructions": "Accept the cookie banner, then finish.",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Replace a recipe 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Replace a recipe 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Replace a recipe 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Replace a recipe 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Replace a recipe 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Replace a recipe 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
patch/v1/recipes/{recipe}

Update a recipe with a complete payload

PATCH currently has the same complete-payload validation as PUT: both name and instructions are required. Updating a recipe owned by another account currently returns 403, while an unknown identifier returns 404.

operationId: updateRecipe

Parameters

Name Location Type Description
recipe *pathstringRecipe public ULID.

Request body

application/json required

Update a recipe with a complete payload request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
instructionsstringRequiredlength: 0–2000
{
  "name": "Open pricing details",
  "instructions": "Open the annual pricing disclosure, then finish."
}

Responses

200The updated recipe.

application/json

Update a recipe with a complete payload 200 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
instructionsstringRequired
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000001",
  "name": "Dismiss cookie banner",
  "instructions": "Accept the cookie banner, then finish.",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Update a recipe with a complete payload 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Update a recipe with a complete payload 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Update a recipe with a complete payload 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Update a recipe with a complete payload 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Update a recipe with a complete payload 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Update a recipe with a complete payload 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
delete/v1/recipes/{recipe}

Delete a recipe

Soft-deletes an account-owned recipe. Existing capture snapshots remain unchanged. Recipes owned by other accounts return 404.

operationId: deleteRecipe

Parameters

Name Location Type Description
recipe *pathstringRecipe public ULID.

Responses

204The recipe was deleted. The response has no body.
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Delete a recipe 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Delete a recipe 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Delete a recipe 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Delete a recipe 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}

Resource

Watermarks

Manage account-owned image watermarks and their placement settings.

get/v1/watermarks

List watermarks

Returns the authenticated account's image watermarks newest first, 20 per page.

operationId: listWatermarks

Parameters

Name Location Type Description
page queryintegerOne-indexed result page. Collections contain 20 records per page.

Responses

200Paginated watermarks.

application/json

List watermarks 200 response fields
FieldType Requirement Description
current_pageintegerRequired
first_page_urlstringRequiredformat: uri
frominteger | nullRequired
last_pageintegerRequired
last_page_urlstringRequiredformat: uri
linksarray<PaginatorLink>Required
next_page_urlstring | nullRequiredformat: uri
pathstringRequiredformat: uri
per_pageintegerRequired
prev_page_urlstring | nullRequiredformat: uri
tointeger | nullRequired
totalintegerRequired
dataarray<Watermark>Required
{
  "current_page": 1,
  "first_page_url": "https://api.example.com/v1/watermarks?page=1",
  "from": null,
  "last_page": 1,
  "last_page_url": "https://api.example.com/v1/watermarks?page=1",
  "links": [],
  "next_page_url": null,
  "path": "https://api.example.com/v1/watermarks",
  "per_page": 20,
  "prev_page_url": null,
  "to": null,
  "total": 0,
  "data": []
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

List watermarks 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
List watermarks 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

List watermarks 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
post/v1/watermarks

Create a watermark

Uploads an account-owned image watermark. Send multipart/form-data. Images may be JPG/JPEG, PNG, or WebP, at most 512 KiB and 4096 by 4096 pixels.

operationId: createWatermark

Request body

multipart/form-data required

Create a watermark request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
imagestringRequiredJPG/JPEG, PNG, or WebP image, at most 512 KiB and 4096 by 4096 pixels.format: binary
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequiredrange: 10–100
scale_percentintegerRequiredrange: 5–50
marginintegerRequiredrange: 0–200
{
  "name": "Product logo",
  "image": "@product-logo.png",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24
}

Responses

201The watermark was created.

application/json

Create a watermark 201 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequired
scale_percentintegerRequired
marginintegerRequired
preview_urlstringRequiredAuthenticated binary image endpoint.format: uri
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000002",
  "name": "Product logo",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24,
  "preview_url": "https://api.example.com/v1/watermarks/01J00000000000000000000002/image",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Create a watermark 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Create a watermark 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Create a watermark 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Create a watermark 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
get/v1/watermarks/{watermark}

Get a watermark

Returns one account-owned watermark and its authenticated image URL. Watermarks owned by other accounts return 404.

operationId: getWatermark

Parameters

Name Location Type Description
watermark *pathstringWatermark public ULID.

Responses

200Watermark details.

application/json

Get a watermark 200 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequired
scale_percentintegerRequired
marginintegerRequired
preview_urlstringRequiredAuthenticated binary image endpoint.format: uri
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000002",
  "name": "Product logo",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24,
  "preview_url": "https://api.example.com/v1/watermarks/01J00000000000000000000002/image",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Get a watermark 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Get a watermark 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Get a watermark 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Get a watermark 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
put/v1/watermarks/{watermark}

Replace watermark settings

Replaces every writable setting. The image cannot be replaced. Updating a watermark owned by another account currently returns 403, while an unknown identifier returns 404.

operationId: replaceWatermark

Parameters

Name Location Type Description
watermark *pathstringWatermark public ULID.

Request body

application/json required

Replace watermark settings request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequiredrange: 10–100
scale_percentintegerRequiredrange: 5–50
marginintegerRequiredrange: 0–200
{
  "name": "Product logo",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24
}

Responses

200The updated watermark.

application/json

Replace watermark settings 200 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequired
scale_percentintegerRequired
marginintegerRequired
preview_urlstringRequiredAuthenticated binary image endpoint.format: uri
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000002",
  "name": "Product logo",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24,
  "preview_url": "https://api.example.com/v1/watermarks/01J00000000000000000000002/image",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Replace watermark settings 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Replace watermark settings 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Replace watermark settings 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Replace watermark settings 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Replace watermark settings 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Replace watermark settings 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
patch/v1/watermarks/{watermark}

Update watermark settings with a complete payload

PATCH currently has the same complete-payload validation as PUT. Send name, position, opacity_percent, scale_percent, and margin; image replacement is prohibited. Cross-account updates currently return 403.

operationId: updateWatermark

Parameters

Name Location Type Description
watermark *pathstringWatermark public ULID.

Request body

application/json required

Update watermark settings with a complete payload request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequiredrange: 10–100
scale_percentintegerRequiredrange: 5–50
marginintegerRequiredrange: 0–200
{
  "name": "Product logo",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24
}

Responses

200The updated watermark.

application/json

Update watermark settings with a complete payload 200 response fields
FieldType Requirement Description
idstringRequiredPublic ULID.
namestringRequired
positiontop-left | top-center | top-right | center-left | center | center-right | bottom-left | bottom-center | bottom-rightRequired
opacity_percentintegerRequired
scale_percentintegerRequired
marginintegerRequired
preview_urlstringRequiredAuthenticated binary image endpoint.format: uri
created_atstring | nullRequiredformat: date-time
updated_atstring | nullRequiredformat: date-time
{
  "id": "01J00000000000000000000002",
  "name": "Product logo",
  "position": "bottom-right",
  "opacity_percent": 80,
  "scale_percent": 20,
  "margin": 24,
  "preview_url": "https://api.example.com/v1/watermarks/01J00000000000000000000002/image",
  "created_at": "2026-07-16T12:00:00+00:00",
  "updated_at": "2026-07-16T12:00:00+00:00"
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Update watermark settings with a complete payload 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Update watermark settings with a complete payload 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Update watermark settings with a complete payload 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Update watermark settings with a complete payload 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Update watermark settings with a complete payload 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Update watermark settings with a complete payload 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
delete/v1/watermarks/{watermark}

Delete a watermark

Deletes an account-owned watermark unless it is referenced by a template or an active queued or processing capture.

operationId: deleteWatermark

Parameters

Name Location Type Description
watermark *pathstringWatermark public ULID.

Responses

204The watermark was deleted. The response has no body.
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Delete a watermark 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Delete a watermark 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
409The watermark is referenced by a template or an active queued or processing capture.

application/json

Delete a watermark 409 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "watermark_not_deletable",
    "message": "Remove this watermark from templates before deleting it."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Delete a watermark 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Delete a watermark 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
get/v1/watermarks/{watermark}/image

Download a watermark image

Returns the authenticated account-owned watermark image as binary data. The response is privately cacheable for five minutes.

operationId: getWatermarkImage

Parameters

Name Location Type Description
watermark *pathstringWatermark public ULID.

Responses

200The stored watermark image.
Download a watermark image 200 response headers
Header Type Example Description
Cache-Controlstringprivate, max-age=300Private five-minute cache policy.
X-Content-Type-OptionsstringPrevents MIME sniffing.

image/jpeg

image/png

image/webp

application/octet-stream

401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Download a watermark image 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Download a watermark image 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Download a watermark image 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Download a watermark image 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}

Resource

Templates

Manage reusable screenshot settings and queue captures from them.

get/v1/templates

List templates

Returns the authenticated account's templates ordered by most recently updated, 20 per page.

operationId: listTemplates

Parameters

Name Location Type Description
page queryintegerOne-indexed result page. Collections contain 20 records per page.

Responses

200Paginated templates.

application/json

List templates 200 response fields
FieldType Requirement Description
current_pageintegerRequired
first_page_urlstringRequiredformat: uri
frominteger | nullRequired
last_pageintegerRequired
last_page_urlstringRequiredformat: uri
linksarray<PaginatorLink>Required
next_page_urlstring | nullRequiredformat: uri
pathstringRequiredformat: uri
per_pageintegerRequired
prev_page_urlstring | nullRequiredformat: uri
tointeger | nullRequired
totalintegerRequired
dataarray<Template>Required
{
  "current_page": 1,
  "first_page_url": "https://api.example.com/v1/templates?page=1",
  "from": null,
  "last_page": 1,
  "last_page_url": "https://api.example.com/v1/templates?page=1",
  "links": [],
  "next_page_url": null,
  "path": "https://api.example.com/v1/templates",
  "per_page": 20,
  "prev_page_url": null,
  "to": null,
  "total": 0,
  "data": []
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

List templates 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
List templates 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

List templates 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
post/v1/templates

Create a template

Creates a reusable screenshot template. The owned watermark_id and recipe_id fields are subject to the same feature gates and ownership rules as screenshot creation. capture_options stores normalized options without url.

operationId: createTemplate

Request body

application/json required

Create a template request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
urlstringRequiredRequired public HTTP or HTTPS URL.format: uri · length: 0–2048
formatpng | jpeg | webp | avifOptionaldefault: "png"
qualityintegerOptionalNon-PNG output defaults to 82; PNG normalizes quality to null.range: 1–100
full_pagebooleanOptionaldefault: false
presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphOptionaldefault: "desktop"
viewportRequestedViewportOptional
viewport.widthintegerOptionalrange: 320–3840
viewport.heightintegerOptionalrange: 240–2160
device_scale_factornumberOptionalrange: 1–3
delay_msintegerOptionaldefault: 0 · range: 0–10000
timeout_msintegerOptionaldefault: 30000 · range: 1000–60000
wait_untilload | domcontentloaded | networkidle0 | networkidle2Optionaldefault: "networkidle2"
wait_for_selectorstring | nullOptionaldefault: null · length: 0–500
dark_modebooleanOptionaldefault: false
reduced_motionbooleanOptionaldefault: true
remove_brandingbooleanOptionaldefault: false
watermark_idstring | nullOptionalOwned watermark public ULID. Requires remove_branding=true and the watermark feature.
recipe_idstring | nullOptionalOwned recipe public ULID. Subject to the recipe feature gate.
{
  "name": "Homepage desktop",
  "url": "https://example.com",
  "format": "png",
  "preset": "desktop",
  "full_page": true
}

Responses

201The template was created.

application/json

Create a template 201 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
namestringRequired
urlstringRequiredformat: uri
capture_optionsTemplateCaptureOptionsRequired
capture_options.formatpng | jpeg | webp | avifRequired
capture_options.qualityinteger | nullRequired
capture_options.full_pagebooleanRequired
capture_options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
capture_options.viewportCaptureViewportRequired
capture_options.delay_msintegerRequired
capture_options.timeout_msintegerRequired
capture_options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
capture_options.wait_for_selectorstring | nullRequired
capture_options.dark_modebooleanRequired
capture_options.reduced_motionbooleanRequired
capture_options.remove_brandingbooleanRequired
capture_options.watermark_idstringOptionalStored public ULID when a custom watermark is selected.
recipeTemplateRecipeSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 42,
  "name": "Homepage desktop",
  "url": "https://example.com",
  "capture_options": {
    "format": "png",
    "quality": null,
    "full_page": true,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "recipe": null,
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Create a template 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Create a template 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Create a template 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Create a template 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
get/v1/templates/{template}

Get a template

Returns one account-owned template. Templates owned by other accounts return 404.

operationId: getTemplate

Parameters

Name Location Type Description
template *pathintegerTemplate integer identifier.

Responses

200Template details.

application/json

Get a template 200 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
namestringRequired
urlstringRequiredformat: uri
capture_optionsTemplateCaptureOptionsRequired
capture_options.formatpng | jpeg | webp | avifRequired
capture_options.qualityinteger | nullRequired
capture_options.full_pagebooleanRequired
capture_options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
capture_options.viewportCaptureViewportRequired
capture_options.delay_msintegerRequired
capture_options.timeout_msintegerRequired
capture_options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
capture_options.wait_for_selectorstring | nullRequired
capture_options.dark_modebooleanRequired
capture_options.reduced_motionbooleanRequired
capture_options.remove_brandingbooleanRequired
capture_options.watermark_idstringOptionalStored public ULID when a custom watermark is selected.
recipeTemplateRecipeSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 42,
  "name": "Homepage desktop",
  "url": "https://example.com",
  "capture_options": {
    "format": "png",
    "quality": null,
    "full_page": true,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "recipe": null,
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Get a template 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Get a template 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Get a template 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Get a template 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
put/v1/templates/{template}

Replace a template

Replaces the template's writable representation. name and url are required; omitted optional capture settings are normalized back to defaults. Updating a template owned by another account currently returns 403.

operationId: replaceTemplate

Parameters

Name Location Type Description
template *pathintegerTemplate integer identifier.

Request body

application/json required

Replace a template request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
urlstringRequiredRequired public HTTP or HTTPS URL.format: uri · length: 0–2048
formatpng | jpeg | webp | avifOptionaldefault: "png"
qualityintegerOptionalNon-PNG output defaults to 82; PNG normalizes quality to null.range: 1–100
full_pagebooleanOptionaldefault: false
presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphOptionaldefault: "desktop"
viewportRequestedViewportOptional
viewport.widthintegerOptionalrange: 320–3840
viewport.heightintegerOptionalrange: 240–2160
device_scale_factornumberOptionalrange: 1–3
delay_msintegerOptionaldefault: 0 · range: 0–10000
timeout_msintegerOptionaldefault: 30000 · range: 1000–60000
wait_untilload | domcontentloaded | networkidle0 | networkidle2Optionaldefault: "networkidle2"
wait_for_selectorstring | nullOptionaldefault: null · length: 0–500
dark_modebooleanOptionaldefault: false
reduced_motionbooleanOptionaldefault: true
remove_brandingbooleanOptionaldefault: false
watermark_idstring | nullOptionalOwned watermark public ULID. Requires remove_branding=true and the watermark feature.
recipe_idstring | nullOptionalOwned recipe public ULID. Subject to the recipe feature gate.
{
  "name": "Homepage mobile",
  "url": "https://example.com",
  "format": "png",
  "preset": "iphone_16",
  "full_page": true
}

Responses

200The updated template.

application/json

Replace a template 200 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
namestringRequired
urlstringRequiredformat: uri
capture_optionsTemplateCaptureOptionsRequired
capture_options.formatpng | jpeg | webp | avifRequired
capture_options.qualityinteger | nullRequired
capture_options.full_pagebooleanRequired
capture_options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
capture_options.viewportCaptureViewportRequired
capture_options.delay_msintegerRequired
capture_options.timeout_msintegerRequired
capture_options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
capture_options.wait_for_selectorstring | nullRequired
capture_options.dark_modebooleanRequired
capture_options.reduced_motionbooleanRequired
capture_options.remove_brandingbooleanRequired
capture_options.watermark_idstringOptionalStored public ULID when a custom watermark is selected.
recipeTemplateRecipeSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 42,
  "name": "Homepage desktop",
  "url": "https://example.com",
  "capture_options": {
    "format": "png",
    "quality": null,
    "full_page": true,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "recipe": null,
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Replace a template 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Replace a template 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Replace a template 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Replace a template 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Replace a template 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Replace a template 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
patch/v1/templates/{template}

Update a template with a complete payload

PATCH currently has the same complete-payload behavior as PUT. Send name, url, and every optional setting that should remain non-default; omitted optional settings reset to defaults. Cross-account updates currently return 403.

operationId: updateTemplate

Parameters

Name Location Type Description
template *pathintegerTemplate integer identifier.

Request body

application/json required

Update a template with a complete payload request fields
FieldType Requirement Description
namestringRequiredlength: 0–80
urlstringRequiredRequired public HTTP or HTTPS URL.format: uri · length: 0–2048
formatpng | jpeg | webp | avifOptionaldefault: "png"
qualityintegerOptionalNon-PNG output defaults to 82; PNG normalizes quality to null.range: 1–100
full_pagebooleanOptionaldefault: false
presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphOptionaldefault: "desktop"
viewportRequestedViewportOptional
viewport.widthintegerOptionalrange: 320–3840
viewport.heightintegerOptionalrange: 240–2160
device_scale_factornumberOptionalrange: 1–3
delay_msintegerOptionaldefault: 0 · range: 0–10000
timeout_msintegerOptionaldefault: 30000 · range: 1000–60000
wait_untilload | domcontentloaded | networkidle0 | networkidle2Optionaldefault: "networkidle2"
wait_for_selectorstring | nullOptionaldefault: null · length: 0–500
dark_modebooleanOptionaldefault: false
reduced_motionbooleanOptionaldefault: true
remove_brandingbooleanOptionaldefault: false
watermark_idstring | nullOptionalOwned watermark public ULID. Requires remove_branding=true and the watermark feature.
recipe_idstring | nullOptionalOwned recipe public ULID. Subject to the recipe feature gate.
{
  "name": "Homepage mobile",
  "url": "https://example.com",
  "format": "png",
  "preset": "iphone_16",
  "full_page": true
}

Responses

200The updated template.

application/json

Update a template with a complete payload 200 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
namestringRequired
urlstringRequiredformat: uri
capture_optionsTemplateCaptureOptionsRequired
capture_options.formatpng | jpeg | webp | avifRequired
capture_options.qualityinteger | nullRequired
capture_options.full_pagebooleanRequired
capture_options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
capture_options.viewportCaptureViewportRequired
capture_options.delay_msintegerRequired
capture_options.timeout_msintegerRequired
capture_options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
capture_options.wait_for_selectorstring | nullRequired
capture_options.dark_modebooleanRequired
capture_options.reduced_motionbooleanRequired
capture_options.remove_brandingbooleanRequired
capture_options.watermark_idstringOptionalStored public ULID when a custom watermark is selected.
recipeTemplateRecipeSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 42,
  "name": "Homepage desktop",
  "url": "https://example.com",
  "capture_options": {
    "format": "png",
    "quality": null,
    "full_page": true,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "recipe": null,
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Update a template with a complete payload 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Update a template with a complete payload 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Update a template with a complete payload 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Update a template with a complete payload 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Update a template with a complete payload 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Update a template with a complete payload 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
delete/v1/templates/{template}

Delete a template

Deletes an account-owned template. Existing captures remain and their template_id becomes null.

operationId: deleteTemplate

Parameters

Name Location Type Description
template *pathintegerTemplate integer identifier.

Responses

204The template was deleted. The response has no body.
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Delete a template 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Delete a template 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Delete a template 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Delete a template 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
post/v1/templates/{template}/screenshots

Queue a screenshot from a template

Queues an asynchronous screenshot using the template's normalized settings and current owned recipe or watermark snapshot. Poll the returned capture through the screenshots endpoint.

operationId: createTemplateScreenshot

Parameters

Name Location Type Description
template *pathintegerTemplate integer identifier.

Responses

202The template screenshot was queued.

application/json

Queue a screenshot from a template 202 response fields
FieldType Requirement Description
idstringRequired
statusqueued | processing | completed | failedRequired
sourceapi | dashboard | template | scheduleRequired
target_urlstringRequiredformat: uri
optionsCaptureOptionsRequired
options.urlstringRequiredformat: uri
options.formatpng | jpeg | webp | avifRequired
options.qualityinteger | nullRequiredrange: 1–100
options.full_pagebooleanRequired
options.presetdesktop | desktop_hd | laptop | tablet | tablet_landscape | iphone_16 | pixel_10 | social_card | open_graphRequired
options.viewportCaptureViewportRequired
options.delay_msintegerRequired
options.timeout_msintegerRequired
options.wait_untilload | domcontentloaded | networkidle0 | networkidle2Required
options.wait_for_selectorstring | nullRequired
options.dark_modebooleanRequired
options.reduced_motionbooleanRequired
options.remove_brandingbooleanRequired
options.watermarkCustomWatermarkSnapshotOptional
image_urlstring | nullRequiredSigned inline image URL while a completed file remains retained.format: uri
download_urlstring | nullRequiredSigned attachment URL while a completed file remains retained.format: uri
expires_atstring | nullRequiredConfigured retention expiry. The usual default is 24 hours, but clients must trust this timestamp.format: date-time
credits_usedintegerRequiredrange: 0–∞
watermarkedbooleanRequiredWhether the separate Capturewell watermark is currently present.
watermark_removalWatermarkRemovalRequired
watermark_removal.eligiblebooleanRequired
watermark_removal.creditsintegerRequiredrange: 0–∞
watermark_removal.removed_atstring | nullRequiredformat: date-time
recipeCaptureRecipeSummary | nullRequired
created_atstring | nullRequiredformat: date-time
metadataCaptureMetadata | nullRequired
errorCaptureStoredError | nullRequired
{
  "id": "01J00000000000000000000000",
  "status": "completed",
  "source": "api",
  "target_url": "https://example.com",
  "options": {
    "url": "https://example.com",
    "format": "png",
    "quality": null,
    "full_page": false,
    "preset": "desktop",
    "viewport": {
      "width": 1440,
      "height": 900,
      "device_scale_factor": 1,
      "mobile": false
    },
    "delay_ms": 0,
    "timeout_ms": 30000,
    "wait_until": "networkidle2",
    "wait_for_selector": null,
    "dark_mode": false,
    "reduced_motion": true,
    "remove_branding": false
  },
  "image_url": "https://example.com/captures/01J00000000000000000000000/file?expires=1784203200&signature=fake",
  "download_url": "https://example.com/captures/01J00000000000000000000000/download?expires=1784203200&signature=fake",
  "expires_at": "2026-07-17T12:00:00+00:00",
  "credits_used": 1,
  "watermarked": true,
  "watermark_removal": {
    "eligible": true,
    "credits": 1,
    "removed_at": null
  },
  "recipe": null,
  "created_at": "2026-07-16T12:00:00+00:00",
  "metadata": {
    "width": 1440,
    "height": 900,
    "format": "png",
    "bytes": 128000,
    "duration_ms": 840
  },
  "error": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Queue a screenshot from a template 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Queue a screenshot from a template 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Queue a screenshot from a template 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429Either the request rate limit was exceeded or the account lacks enough credits. A quota_exceeded response does not include Retry-After and is not rescued synchronously by auto recharge; retry only after the balance has actually increased.
Queue a screenshot from a template 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger37Requests remaining in the current window.
Retry-Afterinteger42Present only when the request limiter, rather than the credit quota, caused the response.
X-RateLimit-Resetinteger1784203242Present when the request limiter supplies a reset timestamp.

application/json

{
  "message": "Too Many Attempts."
}

Resource

Schedules

Manage recurring capture schedules for templates.

get/v1/schedules

List schedules

Returns the authenticated account's schedules ordered by most recently updated, 20 per page.

operationId: listSchedules

Parameters

Name Location Type Description
page queryintegerOne-indexed result page. Collections contain 20 records per page.

Responses

200Paginated schedules.

application/json

List schedules 200 response fields
FieldType Requirement Description
current_pageintegerRequired
first_page_urlstringRequiredformat: uri
frominteger | nullRequired
last_pageintegerRequired
last_page_urlstringRequiredformat: uri
linksarray<PaginatorLink>Required
next_page_urlstring | nullRequiredformat: uri
pathstringRequiredformat: uri
per_pageintegerRequired
prev_page_urlstring | nullRequiredformat: uri
tointeger | nullRequired
totalintegerRequired
dataarray<Schedule>Required
{
  "current_page": 1,
  "first_page_url": "https://api.example.com/v1/schedules?page=1",
  "from": null,
  "last_page": 1,
  "last_page_url": "https://api.example.com/v1/schedules?page=1",
  "links": [],
  "next_page_url": null,
  "path": "https://api.example.com/v1/schedules",
  "per_page": 20,
  "prev_page_url": null,
  "to": null,
  "total": 0,
  "data": []
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

List schedules 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
List schedules 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

List schedules 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
post/v1/schedules

Create a schedule

Creates a recurring schedule for an owned template. daily, weekly, and monthly schedules require time; weekly also requires weekday 1 through 7, and monthly requires month_day 1 through 28.

operationId: createSchedule

Request body

application/json required

Create a schedule request fields
FieldType Requirement Description
template_idintegerRequiredOwned template identifier.format: int64 · range: 1–∞
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequired when frequency = "daily", frequency = "weekly", or frequency = "monthly"Required for daily, weekly, and monthly schedules. Omit or send null for hourly.pattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequiredValid timezone identifier, for example Europe/London.
weekdayinteger | nullRequired when frequency = "weekly"ISO weekday 1 through 7. Required only for weekly schedules.range: 1–7
month_dayinteger | nullRequired when frequency = "monthly"Required only for monthly schedules.range: 1–28
{
  "template_id": 42,
  "enabled": true,
  "frequency": "weekly",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": 1,
  "month_day": null
}

Responses

201The schedule was created.

application/json

Create a schedule 201 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequiredpattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequired
weekdayinteger | nullRequiredrange: 1–7
month_dayinteger | nullRequiredrange: 1–28
next_run_atstring | nullRequiredformat: date-time
last_run_atstring | nullRequiredformat: date-time
last_errorstring | nullRequired
templateScheduleTemplateSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 84,
  "enabled": true,
  "frequency": "daily",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": null,
  "month_day": null,
  "next_run_at": "2026-07-17T08:00:00+00:00",
  "last_run_at": null,
  "last_error": null,
  "template": {
    "id": 42,
    "name": "Homepage desktop",
    "url": "https://example.com"
  },
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Create a schedule 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Create a schedule 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Create a schedule 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Create a schedule 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
get/v1/schedules/{schedule}

Get a schedule

Returns one account-owned schedule. Schedules owned by other accounts return 404.

operationId: getSchedule

Parameters

Name Location Type Description
schedule *pathintegerSchedule integer identifier.

Responses

200Schedule details.

application/json

Get a schedule 200 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequiredpattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequired
weekdayinteger | nullRequiredrange: 1–7
month_dayinteger | nullRequiredrange: 1–28
next_run_atstring | nullRequiredformat: date-time
last_run_atstring | nullRequiredformat: date-time
last_errorstring | nullRequired
templateScheduleTemplateSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 84,
  "enabled": true,
  "frequency": "daily",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": null,
  "month_day": null,
  "next_run_at": "2026-07-17T08:00:00+00:00",
  "last_run_at": null,
  "last_error": null,
  "template": {
    "id": 42,
    "name": "Homepage desktop",
    "url": "https://example.com"
  },
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Get a schedule 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Get a schedule 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Get a schedule 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Get a schedule 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
put/v1/schedules/{schedule}

Replace a schedule

Replaces every writable schedule field, including conditional fields for the selected frequency. Updating a schedule owned by another account currently returns 403.

operationId: replaceSchedule

Parameters

Name Location Type Description
schedule *pathintegerSchedule integer identifier.

Request body

application/json required

Replace a schedule request fields
FieldType Requirement Description
template_idintegerRequiredOwned template identifier.format: int64 · range: 1–∞
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequired when frequency = "daily", frequency = "weekly", or frequency = "monthly"Required for daily, weekly, and monthly schedules. Omit or send null for hourly.pattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequiredValid timezone identifier, for example Europe/London.
weekdayinteger | nullRequired when frequency = "weekly"ISO weekday 1 through 7. Required only for weekly schedules.range: 1–7
month_dayinteger | nullRequired when frequency = "monthly"Required only for monthly schedules.range: 1–28
{
  "template_id": 42,
  "enabled": true,
  "frequency": "daily",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": null,
  "month_day": null
}

Responses

200The updated schedule.

application/json

Replace a schedule 200 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequiredpattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequired
weekdayinteger | nullRequiredrange: 1–7
month_dayinteger | nullRequiredrange: 1–28
next_run_atstring | nullRequiredformat: date-time
last_run_atstring | nullRequiredformat: date-time
last_errorstring | nullRequired
templateScheduleTemplateSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 84,
  "enabled": true,
  "frequency": "daily",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": null,
  "month_day": null,
  "next_run_at": "2026-07-17T08:00:00+00:00",
  "last_run_at": null,
  "last_error": null,
  "template": {
    "id": 42,
    "name": "Homepage desktop",
    "url": "https://example.com"
  },
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Replace a schedule 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Replace a schedule 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Replace a schedule 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Replace a schedule 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Replace a schedule 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Replace a schedule 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
patch/v1/schedules/{schedule}

Update a schedule with a complete payload

PATCH currently has the same complete-payload validation as PUT. Send template_id, enabled, frequency, timezone, and the conditional time, weekday, or month_day fields required by that frequency. Cross-account updates currently return 403.

operationId: updateSchedule

Parameters

Name Location Type Description
schedule *pathintegerSchedule integer identifier.

Request body

application/json required

Update a schedule with a complete payload request fields
FieldType Requirement Description
template_idintegerRequiredOwned template identifier.format: int64 · range: 1–∞
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequired when frequency = "daily", frequency = "weekly", or frequency = "monthly"Required for daily, weekly, and monthly schedules. Omit or send null for hourly.pattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequiredValid timezone identifier, for example Europe/London.
weekdayinteger | nullRequired when frequency = "weekly"ISO weekday 1 through 7. Required only for weekly schedules.range: 1–7
month_dayinteger | nullRequired when frequency = "monthly"Required only for monthly schedules.range: 1–28
{
  "template_id": 42,
  "enabled": true,
  "frequency": "daily",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": null,
  "month_day": null
}

Responses

200The updated schedule.

application/json

Update a schedule with a complete payload 200 response fields
FieldType Requirement Description
idintegerRequiredformat: int64
enabledbooleanRequired
frequencyhourly | daily | weekly | monthlyRequired
timestring | nullRequiredpattern: ^([01][0-9]|2[0-3]):[0-5][0-9]$
timezonestringRequired
weekdayinteger | nullRequiredrange: 1–7
month_dayinteger | nullRequiredrange: 1–28
next_run_atstring | nullRequiredformat: date-time
last_run_atstring | nullRequiredformat: date-time
last_errorstring | nullRequired
templateScheduleTemplateSummary | nullRequired
latest_captureCaptureHistoryItem | nullRequired
{
  "id": 84,
  "enabled": true,
  "frequency": "daily",
  "time": "09:00",
  "timezone": "Europe/London",
  "weekday": null,
  "month_day": null,
  "next_run_at": "2026-07-17T08:00:00+00:00",
  "last_run_at": null,
  "last_error": null,
  "template": {
    "id": 42,
    "name": "Homepage desktop",
    "url": "https://example.com"
  },
  "latest_capture": null
}
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Update a schedule with a complete payload 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
403The authenticated account is not authorized for this operation. Cross-account resource updates currently use this response.

application/json

Update a schedule with a complete payload 403 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "This action is unauthorized."
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Update a schedule with a complete payload 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
422Laravel validation failed. Do not retry unchanged input.

application/json

Update a schedule with a complete payload 422 response fields
FieldType Requirement Description
messagestringRequiredSummary of the first validation error and any additional error count.
errorsobjectRequiredField names map to one or more validation messages. Nested keys use dot notation.
{
  "message": "The url field is required.",
  "errors": {
    "url": [
      "The url field is required."
    ]
  }
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Update a schedule with a complete payload 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Update a schedule with a complete payload 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
delete/v1/schedules/{schedule}

Delete a schedule

Deletes an account-owned schedule without deleting its template.

operationId: deleteSchedule

Parameters

Name Location Type Description
schedule *pathintegerSchedule integer identifier.

Responses

204The schedule was deleted. The response has no body.
401The Bearer key is missing, malformed, revoked, or unknown.

application/json

Delete a schedule 401 response fields
FieldType Requirement Description
errorErrorDetailRequired
error.codestringRequiredStable error identifier. Renderer error codes are extensible strings rather than a closed enum. Known examples include navigation_failed, renderer_unavailable, watermark_unavailable, recipe_not_configured, recipe_planning_failed, recipe_action_not_found, recipe_action_rejected, and recipe_action_limit.
error.messagestringRequired
error.retryablebooleanOptionalWhen present, retry automatically only when true.
{
  "error": {
    "code": "unauthenticated",
    "message": "A valid API key is required."
  }
}
404The identifier was not found or is not visible to the authenticated account.

application/json

Delete a schedule 404 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Not Found"
}
429The 60 requests-per-minute limit was exceeded. Wait for Retry-After before retrying.
Delete a schedule 429 response headers
Header Type Example Description
X-RateLimit-Limitinteger60Maximum requests in the current window.
X-RateLimit-Remaininginteger0Requests remaining in the current window.
Retry-Afterinteger42Seconds to wait before another request.
X-RateLimit-Resetinteger1784203242Unix timestamp when the limiter resets.

application/json

Delete a schedule 429 response fields
FieldType Requirement Description
messagestringRequired
{
  "message": "Too Many Attempts."
}
Back to top