---
title: "Get Job Status"
method: GET
path: "/jobs/{job_id}/status"
tags: ["Jobs"]
---

# Get Job Status

`GET /jobs/{job_id}/status`

## Request

- Base URL: `https://api.hedra.com/v3`
- URL: `https://api.hedra.com/v3/jobs/{job_id}/status`
- Auth: one of:
  - API key in header `Authorization`
  - HTTP bearer

## Path parameters

- `job_id` string, required: The job's id (`job_<uuid>`).

## Query parameters

- `logs_after` string, nullable: Tail this job's lifecycle events incrementally: returns only events newer than this cursor, plus `logs_next_cursor` to send on the next poll. Pass `start` to begin from the job's first event. Omit it and the response carries no events at all — the default polling shape is unchanged.

## Response `200`

Successful Response

- StatusResponse: A job's status, progress, and estimated completion time. Returned by `GET /v3/jobs/{job_id}/status`, and sent as each `status` frame of `GET /v3/jobs/{job_id}/stream`.
  - `job_id` string, required: The job this status describes.
  - `status` 'IN_QUEUE' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED', required: The four states a job can be in.
  - `progress` number, nullable: Estimated fraction of the job completed, from 0 to 1 (not a percentage). While `estimated_completion_at` is non-null, this value is computed from the time since submission and that estimate, so it is only as accurate as the estimate, and it stays below 1. While an `IN_QUEUE` or `IN_PROGRESS` job's `estimated_completion_at` is null, `GET /v3/jobs/{job_id}/status` reports 0. A `COMPLETED` job reports 1. A `FAILED` job's value can be anything from 0 to 1 and does not show how far the job got.
  - `estimated_completion_at` string, date-time, nullable: ISO-8601 instant this job is estimated to finish. A job can finish well before or after it. The estimate can change while the job runs, so read it from each poll. Null once the job is `COMPLETED` or `FAILED`, and while no estimate is available. The submit response also includes it; `GET /v3/jobs/{job_id}` and `GET /v3/jobs` do not.
  - `logs` JobLogItem[], nullable: Lifecycle events newer than the `logs_after` cursor, oldest first. Present only when `logs_after` is supplied; absent from the stream's `status` frames.
    - `id` integer, required: Monotonically increasing id of this event within the job's log. Cursors are separate opaque values (`next_cursor` / `logs_next_cursor`); do not send this id as one.
    - `timestamp` string, date-time, required: ISO-8601 instant the event was recorded.
    - `level` 'info' | 'warning' | 'error', required
    - `event` 'queued' | 'started' | 'moderation.passed' | 'provider.submitted' | 'provider.error' | 'retry.scheduled' | 'progress' | 'finalizing' | 'download.ready' | 'completed' | 'failed' | 'recovered', required
    - `message` string, required: Human-readable summary of the event.
    - `source` 'api' | 'worker' | 'provider' | 'cron', required
    - `data` object: Structured detail specific to this event type; empty when the event carries none.
  - `logs_next_cursor` string, nullable: Cursor to send as `logs_after` on the next poll. Absent when this poll delivered no new events — keep using the cursor you sent.

## Other responses

- `400`: Invalid or failed-validation request.
- `401`: Authentication failed: missing, malformed, or invalid credentials.
- `403`: Insufficient scope or plan.
- `404`: Resource not found.
- `429`: Rate limit exceeded.
- `500`: Internal error.

## Changes

- **2026-10-16** `06692d16e78a`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/hedra-labs/apis/hedra-api/changes/jobs/:job_id/status/get.md)

---

[API](https://skmtc.dev/hedra-labs/apis/hedra-api.md) - [All operations](https://skmtc.dev/hedra-labs/apis/hedra-api/llms.txt) - [OpenAPI document](https://skmtc.dev/hedra-labs/apis/hedra-api/revisions/6ef35a11cefe?raw)
