> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/cvat-ai/cvat/llms.txt
> Use this file to discover all available pages before exploring further.

# Jobs

> Manage annotation jobs via the REST API

## Overview

Jobs represent individual work units within tasks. Each task is automatically divided into jobs based on the configured segment size. Jobs can be assigned to different annotators for parallel work.

## List Jobs

Retrieve a list of all jobs accessible to you.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://app.cvat.ai/api/jobs" \
    -H "Authorization: Token <your_token>"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://app.cvat.ai/api/jobs",
      headers={"Authorization": "Token <your_token>"}
  )
  jobs = response.json()
  ```
</CodeGroup>

### Query Parameters

<ParamField query="task_id" type="integer">
  Filter by task ID
</ParamField>

<ParamField query="task_name" type="string">
  Filter by task name
</ParamField>

<ParamField query="project_id" type="integer">
  Filter by project ID
</ParamField>

<ParamField query="project_name" type="string">
  Filter by project name
</ParamField>

<ParamField query="assignee" type="string">
  Filter by assignee username
</ParamField>

<ParamField query="state" type="string">
  Filter by state: `new`, `in progress`, `completed`, or `rejected`
</ParamField>

<ParamField query="stage" type="string">
  Filter by stage: `annotation`, `validation`, or `acceptance`
</ParamField>

<ParamField query="dimension" type="string">
  Filter by dimension: `2d` or `3d`
</ParamField>

<ParamField query="type" type="string">
  Filter by type: `annotation`, `ground_truth`, or `consensus_replica`
</ParamField>

<ParamField query="parent_job_id" type="integer">
  Filter by parent job ID
</ParamField>

<ParamField query="search" type="string">
  Search jobs by multiple fields
</ParamField>

<ParamField query="sort" type="string">
  Sort by field name
</ParamField>

<ParamField query="page" type="integer">
  Page number for pagination
</ParamField>

<ParamField query="page_size" type="integer">
  Number of results per page
</ParamField>

## Create a Job

Create a new job (typically for ground truth or consensus purposes).

<CodeGroup>
  ```bash cURL - Random Frames theme={null}
  curl -X POST "https://app.cvat.ai/api/jobs" \
    -H "Authorization: Token <your_token>" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "ground_truth",
      "task_id": 42,
      "frame_selection_method": "random_uniform",
      "frame_count": 10,
      "random_seed": 1
    }'
  ```

  ```bash cURL - Manual Frames theme={null}
  curl -X POST "https://app.cvat.ai/api/jobs" \
    -H "Authorization: Token <your_token>" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "ground_truth",
      "task_id": 42,
      "frame_selection_method": "manual",
      "frames": [1, 5, 10, 18]
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://app.cvat.ai/api/jobs",
      headers={"Authorization": "Token <your_token>"},
      json={
          "type": "ground_truth",
          "task_id": 42,
          "frame_selection_method": "random_uniform",
          "frame_count": 10,
          "random_seed": 1
      }
  )
  job = response.json()
  ```
</CodeGroup>

### Request Body

<ParamField body="type" type="string" required>
  Job type: `annotation`, `ground_truth`, or `consensus_replica`
</ParamField>

<ParamField body="task_id" type="integer" required>
  Parent task ID
</ParamField>

<ParamField body="frame_selection_method" type="string" required>
  Frame selection method: `random_uniform`, `random_per_job`, or `manual`
</ParamField>

<ParamField body="frame_count" type="integer">
  Number of frames (for random\_uniform method)
</ParamField>

<ParamField body="frame_share" type="number">
  Percentage of frames as decimal (for random\_uniform method)
</ParamField>

<ParamField body="frames_per_job_count" type="integer">
  Frames per job (for random\_per\_job method)
</ParamField>

<ParamField body="frames_per_job_share" type="number">
  Percentage per job as decimal (for random\_per\_job method)
</ParamField>

<ParamField body="frames" type="array">
  Array of frame numbers (for manual method)
</ParamField>

<ParamField body="random_seed" type="integer">
  Random seed for reproducibility
</ParamField>

### Response

<ResponseField name="id" type="integer">
  Job ID
</ResponseField>

<ResponseField name="task_id" type="integer">
  Parent task ID
</ResponseField>

<ResponseField name="project_id" type="integer">
  Parent project ID
</ResponseField>

<ResponseField name="assignee" type="object">
  Assigned user details
</ResponseField>

<ResponseField name="state" type="string">
  Job state: `new`, `in progress`, `completed`, or `rejected`
</ResponseField>

<ResponseField name="stage" type="string">
  Job stage: `annotation`, `validation`, or `acceptance`
</ResponseField>

<ResponseField name="type" type="string">
  Job type
</ResponseField>

<ResponseField name="start_frame" type="integer">
  First frame number
</ResponseField>

<ResponseField name="stop_frame" type="integer">
  Last frame number
</ResponseField>

## Get Job Details

Retrieve details of a specific job.

```bash theme={null}
curl -X GET "https://app.cvat.ai/api/jobs/{id}" \
  -H "Authorization: Token <your_token>"
```

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

## Update a Job

Update job properties such as assignee, state, or stage.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://app.cvat.ai/api/jobs/{id}" \
    -H "Authorization: Token <your_token>" \
    -H "Content-Type: application/json" \
    -d '{
      "state": "completed",
      "assignee_id": 5
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.patch(
      f"https://app.cvat.ai/api/jobs/{job_id}",
      headers={"Authorization": "Token <your_token>"},
      json={
          "state": "in progress",
          "assignee_id": 5
      }
  )
  updated_job = response.json()
  ```
</CodeGroup>

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

### Request Body

<ParamField body="assignee_id" type="integer">
  User ID to assign the job to
</ParamField>

<ParamField body="state" type="string">
  Job state: `new`, `in progress`, `completed`, or `rejected`
</ParamField>

<ParamField body="stage" type="string">
  Job stage: `annotation`, `validation`, or `acceptance`
</ParamField>

## Delete a Job

Delete a job and its annotations. Only certain job types (like ground truth) can be deleted.

```bash theme={null}
curl -X DELETE "https://app.cvat.ai/api/jobs/{id}" \
  -H "Authorization: Token <your_token>"
```

<Warning>
  Not all jobs can be deleted. Currently, only Ground Truth jobs are removable.
</Warning>

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

## Get Job Annotations

Retrieve annotations for a specific job.

```bash theme={null}
curl -X GET "https://app.cvat.ai/api/jobs/{id}/annotations/" \
  -H "Authorization: Token <your_token>"
```

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

### Response

<ResponseField name="version" type="integer">
  Annotation format version
</ResponseField>

<ResponseField name="tags" type="array">
  Array of image-level tags
</ResponseField>

<ResponseField name="shapes" type="array">
  Array of shape annotations
</ResponseField>

<ResponseField name="tracks" type="array">
  Array of tracked objects
</ResponseField>

## Import Job Annotations

Import annotations into a job from a file.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://app.cvat.ai/api/jobs/{id}/annotations/?format=COCO%201.0" \
    -H "Authorization: Token <your_token>" \
    -F "annotation_file=@annotations.json"
  ```

  ```python Python theme={null}
  import requests

  with open('annotations.json', 'rb') as f:
      files = {'annotation_file': f}
      response = requests.post(
          f"https://app.cvat.ai/api/jobs/{job_id}/annotations/",
          headers={"Authorization": "Token <your_token>"},
          params={"format": "COCO 1.0"},
          files=files
      )
  rq_id = response.json()["rq_id"]
  ```
</CodeGroup>

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

### Query Parameters

<ParamField query="format" type="string">
  Annotation format name
</ParamField>

<ParamField query="filename" type="string">
  Annotation filename (for cloud storage)
</ParamField>

<ParamField query="location" type="string">
  Import location: `local` or `cloud_storage`
</ParamField>

<ParamField query="cloud_storage_id" type="integer">
  Cloud storage ID
</ParamField>

### Response

<ResponseField name="rq_id" type="string">
  Request ID for tracking import status
</ResponseField>

## Update Job Annotations

Update specific annotations within a job.

```bash theme={null}
curl -X PATCH "https://app.cvat.ai/api/jobs/{id}/annotations/?action=create" \
  -H "Authorization: Token <your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "shapes": [
      {
        "type": "rectangle",
        "frame": 0,
        "label_id": 1,
        "points": [100, 100, 200, 200]
      }
    ]
  }'
```

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

### Query Parameters

<ParamField query="action" type="string" required>
  Action to perform: `create`, `update`, or `delete`
</ParamField>

## Replace Job Annotations

Replace all annotations in a job.

```bash theme={null}
curl -X PUT "https://app.cvat.ai/api/jobs/{id}/annotations/" \
  -H "Authorization: Token <your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "version": 0,
    "tags": [],
    "shapes": [],
    "tracks": []
  }'
```

## Delete Job Annotations

Delete all annotations from a job.

```bash theme={null}
curl -X DELETE "https://app.cvat.ai/api/jobs/{id}/annotations/" \
  -H "Authorization: Token <your_token>"
```

## Export Job Dataset

Export a job's dataset in a specific format.

```bash theme={null}
curl -X POST "https://app.cvat.ai/api/jobs/{id}/dataset/export?format=COCO%201.0&save_images=true" \
  -H "Authorization: Token <your_token>"
```

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

### Query Parameters

<ParamField query="format" type="string" required>
  Export format name
</ParamField>

<ParamField query="filename" type="string">
  Output filename
</ParamField>

<ParamField query="save_images" type="boolean" default={false}>
  Include images in export
</ParamField>

<ParamField query="location" type="string">
  Export location: `local` or `cloud_storage`
</ParamField>

<ParamField query="cloud_storage_id" type="integer">
  Cloud storage ID
</ParamField>

### Response

<ResponseField name="rq_id" type="string">
  Request ID for tracking export status
</ResponseField>

## Get Job Data

Retrieve media data for a job (frames, chunks, or context images).

```bash theme={null}
curl -X GET "https://app.cvat.ai/api/jobs/{id}/data?type=frame&number=0&quality=original" \
  -H "Authorization: Token <your_token>" \
  --output frame.jpg
```

### Path Parameters

<ParamField path="id" type="integer" required>
  Unique job identifier
</ParamField>

### Query Parameters

<ParamField query="type" type="string" required>
  Data type: `frame`, `chunk`, or `context_image`
</ParamField>

<ParamField query="number" type="integer">
  Frame or chunk number
</ParamField>

<ParamField query="index" type="integer">
  Chunk index (for chunk type)
</ParamField>

<ParamField query="quality" type="string">
  Quality level: `compressed` or `original`
</ParamField>

## Get Job Data Metadata

Retrieve metadata about job media files.

```bash theme={null}
curl -X GET "https://app.cvat.ai/api/jobs/{id}/data/meta" \
  -H "Authorization: Token <your_token>"
```

## Update Job Data Metadata

Update metadata for job media files.

```bash theme={null}
curl -X PATCH "https://app.cvat.ai/api/jobs/{id}/data/meta" \
  -H "Authorization: Token <your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "deleted_frames": [5, 10, 15]
  }'
```

## Get Job Preview

Retrieve a preview image for a job.

```bash theme={null}
curl -X GET "https://app.cvat.ai/api/jobs/{id}/preview" \
  -H "Authorization: Token <your_token>" \
  --output preview.jpg
```

## Get Job Validation Layout

Get the current validation configuration for a job.

```bash theme={null}
curl -X GET "https://app.cvat.ai/api/jobs/{id}/validation_layout" \
  -H "Authorization: Token <your_token>"
```

## Update Job Validation Layout

Update validation configuration (honeypot frames).

<CodeGroup>
  ```bash cURL - Random theme={null}
  curl -X PATCH "https://app.cvat.ai/api/jobs/{id}/validation_layout" \
    -H "Authorization: Token <your_token>" \
    -H "Content-Type: application/json" \
    -d '{
      "frame_selection_method": "random_uniform"
    }'
  ```

  ```bash cURL - Manual theme={null}
  curl -X PATCH "https://app.cvat.ai/api/jobs/{id}/validation_layout" \
    -H "Authorization: Token <your_token>" \
    -H "Content-Type: application/json" \
    -d '{
      "frame_selection_method": "manual",
      "honeypot_real_frames": [10, 20, 22]
    }'
  ```
</CodeGroup>

<Warning>
  This operation is not protected from race conditions. Ensure no parallel calls happen.
</Warning>

## Example: Job Management Workflow

```python theme={null}
import requests

BASE_URL = "https://app.cvat.ai/api"
HEADERS = {"Authorization": "Token <your_token>"}

# Get all jobs for a task
jobs = requests.get(
    f"{BASE_URL}/jobs",
    headers=HEADERS,
    params={"task_id": 42}
).json()["results"]

# Assign jobs to annotators
for i, job in enumerate(jobs):
    annotator_id = (i % 3) + 1  # Round-robin assignment
    requests.patch(
        f"{BASE_URL}/jobs/{job['id']}",
        headers=HEADERS,
        json={
            "assignee_id": annotator_id,
            "state": "in progress"
        }
    )
    print(f"Assigned job {job['id']} to user {annotator_id}")

# Check job progress
for job in jobs:
    job_detail = requests.get(
        f"{BASE_URL}/jobs/{job['id']}",
        headers=HEADERS
    ).json()
    
    print(f"Job {job['id']}: {job_detail['state']} - "
          f"Assignee: {job_detail['assignee']['username']}")
```
