---
title: "Job Completed"
method: POST
path: "webhookEvents_jobCompleted"
---

# Job Completed

`POST webhookEvents_jobCompleted` (webhook)

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.

## Headers

- `webhook-id` string, required
- `webhook-timestamp` string, required
- `webhook-signature` string, required

## Payload

- JobWebhookEvent — The body of every job webhook event. It carries ids, counts and timestamps only, never file names, file paths, error messages or `custom_metadata`.
  - `id` string, required — `evt_` followed by the job id. The same for every delivery of this job's event.
  - `type` 'job.completed' | 'job.completed_with_errors' | 'job.failed' | 'job.timed_out' | 'job.cancelled', required — The event name.
  - `timestamp` string, date-time, required — When the job finished, in ISO 8601 UTC.
  - `data` JobWebhookEventData, required — The indexing job the event reports on.
    - `job_id` string, required — The indexing job's id, as returned when the job was started.
    - `status` 'completed' | 'completed_with_errors' | 'failed' | 'timed_out' | 'cancelled', required — The job's final status. It matches the event name: `job.completed` carries `completed`, and so on.
    - `source` 'api' | 'sync', required — `api` when the job was started by a call to an index endpoint, `sync` when a storage sync started it.
    - `job_type` string, nullable — The kind of indexing job, for example `index_s3_directory`.
    - `collection_id` string, nullable — The id of the collection the job indexed into.
    - `collection_name` string, nullable — The collection's name. `null` when an endpoint receiving the event has `include_collection_name` set to `false`.
    - `environment` string, required — The environment the job ran in: `development`, `staging` or `production`. Endpoints belong to the organization and receive jobs from every environment.
    - `sync_id` string, nullable — The sync that started the job, or `null` for jobs started through the API.
    - `created_at` string, date-time, nullable — When the job was created, in ISO 8601 UTC.
    - `completed_at` string, date-time, nullable — When the job finished, in ISO 8601 UTC.
    - `files` JobWebhookFiles, required — 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.
    - `error_code` string, 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.
    - `test` boolean, required — `true` for a test event, `false` for a real job.
    - `url` string, uri, required — The job's status URL on the Captain API. Fetch it for per-file detail.

## Acknowledgement `200`

Webhook received successfully

---

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