> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openinary.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Queue Jobs

> List, retry, cancel, and delete video processing jobs

**Self-hosted only.** Cloud exposes `/queue/events` only.

Four endpoints over the video job queue: list jobs, then retry, cancel or delete one by ID. All of them need an API key.

```bash theme={null}
curl "https://media.example.com/queue/jobs?status=error&limit=20" \
  -H "Authorization: Bearer <api_key>"
```

## List jobs

```
GET /queue/jobs
```

**Auth:** API Key required

| Param | Type | Default | Notes |
| - | - | - | - |
| `limit` | number | `50` | Maximum number of jobs to return |
| `offset` | number | `0` | Number of jobs to skip. Ignored whenever `status` is set |
| `status` | string | | One of `pending` `processing` `completed` `error` `cancelled` |

The filtered path calls `getJobsByStatus(status, limit)`, which takes no offset. Paginating a filtered list re-returns the same first page. `offset` is echoed back in the response either way.

### Response

This endpoint serves database rows as they are stored. Field names are `snake_case`, not `camelCase`, and timestamps are epoch milliseconds, not ISO 8601 strings.

```json theme={null}
{
  "jobs": [
    {
      "id": "job_abc123",
      "file_path": "videos/clip.mp4",
      "params_json": "{\"width\":640}",
      "cache_path": "cache/w_640/videos/clip.mp4",
      "status": "completed",
      "priority": 2,
      "progress": 100,
      "error": null,
      "retry_count": 0,
      "max_retries": 3,
      "created_at": 1773567000000,
      "started_at": 1773568200000,
      "completed_at": 1773568305000
    }
  ],
  "limit": 50,
  "offset": 0,
  "count": 1
}
```

`count` is the number of jobs in this response, not the total matching the filter.

Each entry in `jobs`:

| Field | Type | Notes |
| - | - | - |
| `id` | string | Unique job identifier |
| `file_path` | string | Storage path of the video being processed |
| `params_json` | string | Transformation parameters the job was queued with, as a JSON string. With `file_path`, this is the key a job is looked up by |
| `cache_path` | string | Where the finished variant is written |
| `status` | string | `pending` `processing` `completed` `error` `cancelled` |
| `priority` | number | Lower runs first. Thumbnails are queued at `1`, transformations at `2` |
| `progress` | number | Progress percentage, 0 to 100 |
| `error` | string | Error message when `status` is `error`, `null` otherwise |
| `retry_count` | number | Attempts made so far |
| `max_retries` | number | Attempt ceiling, from `VIDEO_JOB_RETRY_MAX` |
| `created_at` | number | Epoch milliseconds when the job was queued |
| `started_at` | number | Epoch milliseconds when processing started, `null` while pending |
| `completed_at` | number | Epoch milliseconds when processing finished, `null` until then |

[Video Status](https://docs.openinary.dev/api-reference/video/status.md) returns the same jobs in a converted shape: `camelCase` keys and ISO 8601 timestamps. The two endpoints disagree on field names by design. One serves rows, the other serves a view model.

## Retry job

```
POST /queue/jobs/{jobId}/retry
```

Re-queues a failed job. `jobId` must have `error` status.

```bash theme={null}
curl -X POST https://media.example.com/queue/jobs/job_abc123/retry \
  -H "Authorization: Bearer <api_key>"
```

```json theme={null}
{
  "success": true,
  "message": "Job scheduled for retry"
}
```

**Status codes:** `200` success · `400` job not in error state · `500` error

## Cancel job

```
POST /queue/jobs/{jobId}/cancel
```

Cancels a job before it starts processing. `jobId` must have `pending` status.

```bash theme={null}
curl -X POST https://media.example.com/queue/jobs/job_abc123/cancel \
  -H "Authorization: Bearer <api_key>"
```

```json theme={null}
{
  "success": true,
  "message": "Job cancelled"
}
```

**Status codes:** `200` success · `400` job not pending · `500` error

## Delete job

```
DELETE /queue/jobs/{jobId}
```

Permanently removes a job record from the queue.

```bash theme={null}
curl -X DELETE https://media.example.com/queue/jobs/job_abc123 \
  -H "Authorization: Bearer <api_key>"
```

```json theme={null}
{
  "success": true,
  "message": "Job deleted"
}
```

**Status codes:** `200` success · `400` failed · `500` error

## Related

> [card] [Queue Statistics](https://docs.openinary.dev/api-reference/queue/stats.md)
>
> Aggregate counts per status.

> [card] [Queue Events (SSE)](https://docs.openinary.dev/api-reference/queue/events.md)
>
> Real-time progress updates.

> [card] [Video Status](https://docs.openinary.dev/api-reference/video/status.md)
>
> Check processing status by file path.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.