---
title: "Get the status and download URLs for a batch job"
method: GET
path: "/batch/{batch_id}"
tags: ["Batch APIs"]
---

# Get the status and download URLs for a batch job

`GET /batch/{batch_id}`

Poll the current state of a batch job. The `status` moves `pending` → `processing` →
`completed` or `failed`. When the job is `completed`, the response includes a `download_url`
for the merged results file and `download_urls` for the same data split into parts; both are
pre-signed links valid for **5 days**. When the job is `failed`, `error_message` carries a
human-readable reason.

Results files are gzipped JSONL (one record per line). Enrichment job records are wrapped in
an `{original_identifier, internal_id, data}` envelope; search job records are flat and match
the corresponding non-batch endpoint's record shape.

The `x-api-version` header is not required on this endpoint.

## Path parameters

- `batch_id` string, uuid, required

## Response `200`

Current state of the batch job, with download links when completed

- BatchJobDetailResponse — Current state of a batch job. `download_url` and `download_urls` appear only when `status` is `completed`; `error_message` appears only when the job has an error. Note that a completed job with `result_count: 0` may still include a `download_url` that points to a file that was never written (fetching it returns `404`) — check `result_count` before downloading.
  - `batch_id` string, uuid, required — Unique ID of the batch job.
  - `status` 'pending' | 'processing' | 'completed' | 'failed', required — Job lifecycle status. Moves `pending` → `processing` → `completed` or `failed`.
  - `entity` string, required — Entity type the job operates on (`company` or `person`).
  - `action` string, required — Internal action name for the job (`enrich`, `enrich_live`, `search`, or `search_live`).
  - `identifier_count` integer, required — Number of identifiers submitted. Search jobs always report `1` (the query).
  - `result_count` integer, required — Number of records the job has produced so far. For completed jobs, this is the number of lines in the results file.
  - `entities_requested` integer, required — Number of entities the job was asked to produce.
  - `entities_fulfilled` integer, required — Number of entities actually delivered. May be lower than `entities_requested` when some identifiers cannot be resolved; for search jobs it equals `result_count` and may exceed `entities_requested`.
  - `created_at` string, date-time, nullable, required — When the job was submitted (ISO 8601).
  - `completed_at` string, date-time, nullable, required — When the job finished (ISO 8601). `null` while the job is still pending or processing.
  - `error_message` string — Human-readable reason the job failed (for example, when the processing workflow could not be started). Present only when the job has an error.
  - `download_url` string, uri — Pre-signed URL for the single merged results file (gzipped JSONL, one record per line). Present only for completed jobs. The real URL carries signed authentication query parameters (elided in the example) and stays valid for 5 days.
  - `download_urls` string[] — Pre-signed URLs for the same data split into part files, useful for streaming very large result sets. Present only for completed jobs that wrote results. The real URLs carry signed authentication query parameters (elided in the example) and stay valid for 5 days.

## Other responses

- `401` — Unauthorized — invalid or missing API key
- `404` — Batch job not found or does not belong to the authenticated account

---

[API](https://skmtc.dev/crustdata/apis/batch-api.md) · [All operations](https://skmtc.dev/crustdata/apis/batch-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/crustdata/batch-api/revisions/581689e66ae7/schema)
