---
title: "Sent to `webhook_url` when a background job ends"
method: POST
path: "screenshotFinished"
tags: ["Jobs"]
---

# Sent to \`webhook_url\` when a background job ends

`POST screenshotFinished` (webhook)

The body is the job exactly as `GET /api/v1/jobs/{id}` returns it, plus `event`. Signed with two headers: `x-timestamp` (Unix seconds when this attempt was signed) and `x-signature`, the hex HMAC-SHA256 of `<x-timestamp>.<raw body>` keyed with your secret key. Refuse a delivery whose timestamp is more than 5 minutes from your clock, so a captured delivery cannot be replayed. Other headers: `x-webhook-event`, `x-job-id`, `x-webhook-attempt`. Answer with any 2xx status; other answers are retried with a growing delay.

## Payload

- WebhookEvent: Body POSTed to `webhook_url` when a job ends: the `Job` object plus `event`. Signed with the `x-signature` header (hex HMAC-SHA256 of `<x-timestamp>.<raw body>`, keyed with the secret key).
  - `job_id` string, required
  - `batch_id` string, nullable
  - `status` 'queued' | 'processing' | 'done' | 'failed', required
  - `job_url` string, uri, required
  - `screenshot` ScreenshotFile
    - `id` string, required: Reference id of the render.
    - `url` string, uri, nullable, required: Link to the stored file. It carries its own expiring token and needs no access key.
    - `format` 'png' | 'jpeg' | 'webp' | 'pdf' | 'mp4' | 'webm' | 'gif', required
    - `bytes` integer, required
    - `width` integer, nullable
    - `height` integer, nullable
    - `render_ms` integer, nullable
    - `cached` boolean: True when a stored copy was served.
    - `expires_at` string, date-time, nullable: When the stored file is removed and its link stops working.
  - `error_code` 'invalid_url' | 'host_not_allowed' | 'navigation_failed' | 'timeout' | 'selector_not_found' | 'page_blocked' | 'concurrency_limit' | 'content_too_large' | 'internal_error' | 'renderer_busy' | 'renderer_unavailable' | 'invalid_options' | 'access_key_required' | 'access_key_invalid' | 'signature_required' | 'signature_invalid' | 'quota_exceeded' | 'rate_limited' | 'job_not_found' | 'service_unavailable' | 'invalid_request' | 'email_not_verified' | 'feature_not_available' | 'request_expired' | 'not_found' | 'file_not_found' | 'method_not_allowed' | 'queue_limit' | 'failure_limit' | 'null', nullable
  - `error_message` string, nullable
  - `created_at` string, date-time
  - `finished_at` string, date-time, nullable
  - `event` 'screenshot.completed' | 'screenshot.failed', required

## Acknowledgement `200`

Received.

---

[API](https://skmtc.dev/curlshot/apis/curlshot-api.md) · [All operations](https://skmtc.dev/curlshot/apis/curlshot-api/llms.txt) · [OpenAPI document](https://skmtc.dev/curlshot/apis/curlshot-api/revisions/2022db7875af?raw)
