> For a complete page index of the Captain API documentation, fetch https://docs.captain.dev/llms.txt?excludeSpec=true

# job.completed

POST 

Sent when an indexing job finishes and every file in it was indexed or skipped. The job's final status is `completed` and `data.error_code` is `null`.

Every file from the job is searchable when this event arrives. Jobs that include video or audio send the event after embedding finishes, so the media is searchable too.

Each indexing job sends exactly one event, when it reaches its final status. See [Webhooks](/guides/webhooks) to add an endpoint and verify signatures.

Reference: https://docs.runcaptain.com/reference/webhooks/events/job-completed

## Request

### Headers

- `webhook-id` (string, required) — A unique id for this message. It stays the same on every retry and resend. Deduplicate on it.
- `webhook-timestamp` (string, required) — When this attempt was sent, in Unix seconds.
- `webhook-signature` (string, required) — One or more space-separated signatures, each `v1,` followed by a base64 HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{body}` made with the endpoint's signing secret.

### Payload

- `id` (string, required) — `evt_` followed by the job id. The same for every delivery of this job's event.
- `type` (enum, required) — The event name.
  - Allowed values: `job.completed`, `job.completed_with_errors`, `job.failed`, `job.timed_out`, `job.cancelled`
- `timestamp` (string, required) — When the job finished, in ISO 8601 UTC.
- `data` (JobWebhookEventData, required) — The indexing job the event reports on.

## Types

### JobWebhookEventData

The indexing job the event reports on.

- `job_id` (string, required) — The indexing job's id, as returned when the job was started.
- `status` (enum, required) — The job's final status. It matches the event name: `job.completed` carries `completed`, and so on.
  - Allowed values: `completed`, `completed_with_errors`, `failed`, `timed_out`, `cancelled`
- `source` (enum, required) — `api` when the job was started by a call to an index endpoint, `sync` when a storage sync started it.
  - Allowed values: `api`, `sync`
- `environment` (string, required) — The environment the job ran in: `development`, `staging` or `production`. Endpoints belong to the organization and receive jobs from every environment.
- `files` (JobWebhookFiles, required) — File counts for the job when it finished.
- `test` (boolean, required) — `true` for a test event, `false` for a real job.
- `url` (string, required) — The job's status URL on the Captain API. Fetch it for per-file detail.
- `job_type` (string, optional, nullable) — The kind of indexing job, for example `index_s3_directory`.
- `collection_id` (string, optional, nullable) — The id of the collection the job indexed into.
- `collection_name` (string, optional, nullable) — The collection's name. `null` when an endpoint receiving the event has `include_collection_name` set to `false`.
- `sync_id` (string, optional, nullable) — The sync that started the job, or `null` for jobs started through the API.
- `created_at` (string, optional, nullable) — When the job was created, in ISO 8601 UTC.
- `completed_at` (string, optional, nullable) — When the job finished, in ISO 8601 UTC.
- `error_code` (string, optional, nullable) — Why the job did not fully succeed. Known values are `all_files_failed`, `execution_failed`, `timed_out` and `embedding_stalled`. `null` when the job completed. New values may be added, so treat an unknown value as a failure rather than rejecting the event.

### JobWebhookFiles

File counts for the job when it finished.

- `total` (integer, required) — Files in the job.
- `indexed` (integer, required) — Files indexed.
- `failed` (integer, required) — Files that failed.
- `skipped` (integer, required) — Files skipped, for example because `skip_existing` matched an existing document.