> ## 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.

# Annotations

> Work with annotation data via the REST API

## Overview

Annotations in CVAT include shapes (rectangles, polygons, polylines, points, cuboids, ellipses, masks), tracks (objects tracked across frames), and tags (frame-level labels). Annotations can be managed at the project, task, or job level.

## Annotation Format

CVAT uses a standardized JSON format for annotations:

```json theme={null}
{
  "version": 0,
  "tags": [
    {
      "frame": 0,
      "label_id": 1,
      "group": 0,
      "source": "manual",
      "attributes": []
    }
  ],
  "shapes": [
    {
      "type": "rectangle",
      "frame": 0,
      "label_id": 1,
      "group": 0,
      "source": "manual",
      "attributes": [],
      "points": [100, 100, 200, 200],
      "occluded": false
    }
  ],
  "tracks": [
    {
      "label_id": 1,
      "frame": 0,
      "group": 0,
      "source": "manual",
      "attributes": [],
      "shapes": [
        {
          "type": "rectangle",
          "frame": 0,
          "points": [100, 100, 200, 200],
          "occluded": false,
          "outside": false,
          "attributes": []
        }
      ]
    }
  ]
}
```

## Shape Types

CVAT supports the following shape types:

### Rectangle

Bounding boxes defined by two points (top-left and bottom-right):

```json theme={null}
{
  "type": "rectangle",
  "points": [x1, y1, x2, y2]
}
```

### Polygon

Closed polygons defined by multiple points:

```json theme={null}
{
  "type": "polygon",
  "points": [x1, y1, x2, y2, x3, y3, ...]
}
```

### Polyline

Open polylines:

```json theme={null}
{
  "type": "polyline",
  "points": [x1, y1, x2, y2, x3, y3, ...]
}
```

### Points

Multiple individual points:

```json theme={null}
{
  "type": "points",
  "points": [x1, y1, x2, y2, ...]
}
```

### Cuboid

3D bounding boxes (8 points):

```json theme={null}
{
  "type": "cuboid",
  "points": [x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8]
}
```

### Ellipse

Ellipses defined by center and two radii:

```json theme={null}
{
  "type": "ellipse",
  "points": [cx, cy, rx, ry]
}
```

### Mask

Binary masks (raster format):

```json theme={null}
{
  "type": "mask",
  "points": [left, top, right, bottom]
}
```

## Get Annotations

Annotations can be retrieved at different levels:

### Get Task Annotations

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

### Get Job Annotations

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

### Response Format

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

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

  <ResponseField name="frame" type="integer">
    Frame number
  </ResponseField>

  <ResponseField name="label_id" type="integer">
    Label identifier
  </ResponseField>

  <ResponseField name="group" type="integer">
    Group identifier for related annotations
  </ResponseField>

  <ResponseField name="source" type="string">
    Annotation source: `manual`, `auto`, or `file`
  </ResponseField>

  <ResponseField name="attributes" type="array">
    Array of attribute values
  </ResponseField>
</ResponseField>

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

  <ResponseField name="type" type="string">
    Shape type: `rectangle`, `polygon`, `polyline`, `points`, `cuboid`, `ellipse`, or `mask`
  </ResponseField>

  <ResponseField name="frame" type="integer">
    Frame number
  </ResponseField>

  <ResponseField name="label_id" type="integer">
    Label identifier
  </ResponseField>

  <ResponseField name="points" type="array">
    Array of coordinate values
  </ResponseField>

  <ResponseField name="occluded" type="boolean">
    Whether the object is occluded
  </ResponseField>

  <ResponseField name="group" type="integer">
    Group identifier
  </ResponseField>

  <ResponseField name="source" type="string">
    Annotation source
  </ResponseField>

  <ResponseField name="attributes" type="array">
    Array of attribute values
  </ResponseField>
</ResponseField>

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

  <ResponseField name="label_id" type="integer">
    Label identifier
  </ResponseField>

  <ResponseField name="frame" type="integer">
    Starting frame number
  </ResponseField>

  <ResponseField name="group" type="integer">
    Group identifier
  </ResponseField>

  <ResponseField name="source" type="string">
    Annotation source
  </ResponseField>

  <ResponseField name="shapes" type="array">
    Array of shape positions per frame
  </ResponseField>
</ResponseField>

## Create Annotations

Add new annotations using the PATCH endpoint with `action=create`.

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

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

  shapes = [{
      "type": "rectangle",
      "frame": 0,
      "label_id": 1,
      "group": 0,
      "source": "manual",
      "occluded": False,
      "points": [100, 100, 200, 200],
      "attributes": []
  }]

  response = requests.patch(
      f"https://app.cvat.ai/api/tasks/{task_id}/annotations/",
      headers={"Authorization": "Token <your_token>"},
      params={"action": "create"},
      json={"shapes": shapes}
  )
  ```
</CodeGroup>

### Path Parameters

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

### Query Parameters

<ParamField query="action" type="string" required>
  Must be `create`
</ParamField>

### Request Body

<ParamField body="shapes" type="array">
  Array of shape objects to create
</ParamField>

<ParamField body="tags" type="array">
  Array of tag objects to create
</ParamField>

<ParamField body="tracks" type="array">
  Array of track objects to create
</ParamField>

## Update Annotations

Modify existing annotations using `action=update`.

```bash theme={null}
curl -X PATCH "https://app.cvat.ai/api/tasks/{id}/annotations/?action=update" \
  -H "Authorization: Token <your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "shapes": [
      {
        "id": 123,
        "frame": 0,
        "points": [150, 150, 250, 250],
        "occluded": true
      }
    ]
  }'
```

### Query Parameters

<ParamField query="action" type="string" required>
  Must be `update`
</ParamField>

### Request Body

Include the `id` field for each annotation to update, along with the fields to modify.

## Delete Annotations

Remove specific annotations using `action=delete`.

```bash theme={null}
curl -X PATCH "https://app.cvat.ai/api/tasks/{id}/annotations/?action=delete" \
  -H "Authorization: Token <your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "shapes": [
      {"id": 123},
      {"id": 124}
    ]
  }'
```

### Query Parameters

<ParamField query="action" type="string" required>
  Must be `delete`
</ParamField>

## Replace All Annotations

Replace all annotations in a task or job.

```bash theme={null}
curl -X PUT "https://app.cvat.ai/api/tasks/{id}/annotations/" \
  -H "Authorization: Token <your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "version": 0,
    "tags": [],
    "shapes": [
      {
        "type": "rectangle",
        "frame": 0,
        "label_id": 1,
        "points": [100, 100, 200, 200],
        "occluded": false,
        "group": 0,
        "source": "manual",
        "attributes": []
      }
    ],
    "tracks": []
  }'
```

<Warning>
  This operation replaces ALL existing annotations. Use with caution.
</Warning>

## Delete All Annotations

Remove all annotations from a task or job.

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

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

## Import Annotations

Import annotations from various formats.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://app.cvat.ai/api/tasks/{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:
      response = requests.post(
          f"https://app.cvat.ai/api/tasks/{task_id}/annotations/",
          headers={"Authorization": "Token <your_token>"},
          params={"format": "COCO 1.0"},
          files={"annotation_file": f}
      )
  rq_id = response.json()["rq_id"]
  print(f"Import started: {rq_id}")
  ```
</CodeGroup>

### Supported Import Formats

* COCO 1.0
* YOLO 1.1
* Pascal VOC 1.1
* CVAT 1.1
* LabelMe 3.0
* KITTI 1.0
* MOT 1.1
* And many more...

Get the full list at: `/api/server/annotation/formats`

### Path Parameters

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

### Query Parameters

<ParamField query="format" type="string">
  Import 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>

Check status: `GET /api/requests/{rq_id}`

## Export Annotations

Export annotations in various formats.

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

### Supported Export Formats

* COCO 1.0
* YOLO 1.1
* Pascal VOC 1.1
* CVAT 1.1
* TFRecord 1.0
* Segmentation mask 1.1
* And many more...

### 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>

## Working with Tracks

Tracks represent objects that persist across multiple frames.

### Create a Track

```python theme={null}
track = {
    "label_id": 1,
    "frame": 0,
    "group": 0,
    "source": "manual",
    "attributes": [],
    "shapes": [
        {
            "type": "rectangle",
            "frame": 0,
            "points": [100, 100, 200, 200],
            "occluded": False,
            "outside": False,
            "attributes": []
        },
        {
            "type": "rectangle",
            "frame": 1,
            "points": [105, 105, 205, 205],
            "occluded": False,
            "outside": False,
            "attributes": []
        },
        {
            "type": "rectangle",
            "frame": 2,
            "points": [110, 110, 210, 210],
            "occluded": False,
            "outside": False,
            "attributes": []
        }
    ]
}

requests.patch(
    f"https://app.cvat.ai/api/tasks/{task_id}/annotations/",
    headers=headers,
    params={"action": "create"},
    json={"tracks": [track]}
)
```

### Track Properties

<ParamField body="outside" type="boolean">
  Whether the object is outside the frame (not visible but still tracked)
</ParamField>

<ParamField body="keyframe" type="boolean">
  Whether this frame is a keyframe for interpolation
</ParamField>

## Example: Batch Annotation

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

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

# Create multiple annotations at once
annotations = {
    "shapes": [],
    "tracks": [],
    "tags": []
}

# Add rectangles on different frames
for frame in range(10):
    annotations["shapes"].append({
        "type": "rectangle",
        "frame": frame,
        "label_id": 1,
        "group": 0,
        "source": "auto",
        "occluded": False,
        "points": [100 + frame*10, 100, 200 + frame*10, 200],
        "attributes": []
    })

# Create all annotations
response = requests.patch(
    f"{BASE_URL}/tasks/{task_id}/annotations/",
    headers=HEADERS,
    params={"action": "create"},
    json=annotations
)

print(f"Created {len(annotations['shapes'])} annotations")

# Export to COCO format
export_response = requests.post(
    f"{BASE_URL}/tasks/{task_id}/dataset/export",
    headers=HEADERS,
    params={"format": "COCO 1.0", "save_images": False}
)

rq_id = export_response.json()["rq_id"]
print(f"Export request: {rq_id}")
```

## Get Supported Formats

Retrieve a list of all supported annotation formats:

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

This returns importers and exporters with their specifications and options.
