Capturewell API documentation
Reference documentation for every public endpoint, including request fields, responses, errors, and retry guidance.
- Base URL
- https://api.capturewell.app
- Authentication
- Bearer cw_…
- Output formats
pngjpegwebpavifpdf
On this page
API reference formats
Read the endpoint reference, or use the OpenAPI JSON endpoint with code generators and other development tools.
API keys
Authenticate requests with a revocable API key beginning with cw_.
Asynchronous captures
Queue long-running captures, then poll or receive a signed terminal webhook.
Retry behavior
Error codes and response headers explain whether and when to retry a request.
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.
Identify the account and check available credits.
Call GET /v1/account to retrieve the API key owner's id, name, email, and avatar. The response separates monthly and purchased credit balances, including reservations, and provides total_available for the combined usable balance.
curl "https://api.capturewell.app/v1/account" \
-H "Authorization: Bearer $CAPTUREWELL_API_KEY" \
-H "Accept: application/json"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
}'Poll or receive a signed terminal event.
queuedprocessingcompletedfailed 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.
Images or a fixed A4 PDF.
PNG, JPEG, WebP, and AVIF work with synchronous or asynchronous capture. PDF is asynchronous only, starts at two credits, and renders the full prepared page as a paginated portrait A4 document using screen media, backgrounds, and zero margins. A synchronous PDF request returns pdf_requires_async before creating a capture or reserving credits.
With format: "pdf", omit quality, full_page, device_scale_factor, and watermark_id. Required Capturewell branding must be removed explicitly at creation with remove_branding: true and its configured credit. Use file_url for every format; image_url is null for PDF, and PDF width and height are source-document CSS pixels. All files remain temporary.
Queue 1–10 URLs atomically.
Send one ordered urls array and one shared option set to POST /v1/screenshot-batches. Validation, ownership, or insufficient credits creates nothing. After a 202 response, poll GET /v1/screenshot-batches/{id}; items retain request order and complete or fail independently through the ordinary capture lifecycle. Creation is limited to five requests per minute.
Batches do not accept webhooks, delivery to your storage, templates, schedules, or per-item options. In the dashboard, open New captures, enable Batch, and enter one URL per line; the same capture settings apply to every URL, and progress appears under Recent batches.
Verify the raw body, then deduplicate the event.
Configure one public HTTPS endpoint with PUT /v1/webhook-endpoint and store the returned signing secret: it is shown once. Then pass webhook: true to an asynchronous capture. Capturewell snapshots the current endpoint for that capture and emits capture.completed or capture.failed. Any 2xx response acknowledges delivery.
Parse X-Capturewell-Signature as t=timestamp,v1=hex-hmac and compare HMAC-SHA256 of timestamp.raw-json in constant time. Reject timestamps outside five minutes and deduplicate the at-least-once retries by X-Capturewell-Event-Id. Signed result URLs inside completed events still expire.
The dashboard Webhooks card can save, rotate, test, or delete the endpoint. Send test emits a single signed webhook.test event. Enable delivery per capture in New captures; Batch mode does not support webhooks. Webhook failure never changes capture status or credits, and deleting or expiring a capture cancels a still-pending delivery.
Deliver to your storage with one short-lived presigned PUT URL.
An asynchronous capture may include a public HTTPS delivery_url. Capturewell streams the retained result in one PUT with its exact Content-Type and Content-Length. The URL must authorize those headers and remain valid through rendering and retries. Custom headers, provider credentials, ACLs, metadata, cookies, and multipart uploads are not supported, and the encrypted URL is never returned.
Delivery is at least once and must safely overwrite the same object. Its independent state appears in external_delivery; upload failure does not change capture completion, credits, webhooks, or Capturewell's temporary retention. This option is API-only and is not accepted by synchronous, dashboard, template, schedule, or batch creation.
To copy a completed, unexpired retained result again, send a new URL to POST /v1/screenshots/{id}/delivery. Re-delivery is limited to ten requests per minute, rejects an already-pending delivery, does not re-render or consume credits, and uses the file's current watermark state. Deleting the Capturewell capture never deletes the customer's object.
Follow page links and preserve identifier types.
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.
| Resource | Path parameter | Type | Example |
|---|---|---|---|
| Captures | capture | string | 01J00000000000000000000000 |
| Capture batches | captureBatch | string | 01J00000000000000000000010 |
| Recipes | recipe | string | 01J00000000000000000000001 |
| Watermarks | watermark | string | 01J00000000000000000000002 |
| Templates | template | integer | 42 |
| Schedules | schedule | integer | 84 |
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.
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 | An applicable request throttle or quota exhaustion. | Honor Retry-After for throttling; add credits for quota_exceeded. The default is 60/minute, batch creation is 5/minute, and re-delivery is 10/minute. |
| 503 | A service is unavailable, or a committed batch needs deferred queue dispatch. | Follow error.retryable. For batch_dispatch_deferred, poll the returned batch_id and do not repeat creation. |
Screenshot creation has no idempotency key, so do not blindly replay an ambiguous request. To retry an owned failed capture explicitly, use POST /v1/screenshots/{id}/retry. It creates a new queued capture and reserves credits at current pricing; it does not modify the failed capture, copy its webhook request, or copy its request to deliver to your storage.