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

# Exports API

> API reference for exporting annotated data

Export annotation results from datasets and projects.

## List Exports

```
GET /api/v1/exports/
```

Returns all exports visible to the authenticated user, ordered by most recent first.

### Parameters

| Name       | Type    | Required | Description                                  |
| ---------- | ------- | -------- | -------------------------------------------- |
| `ordering` | string  | No       | Field to order results by (query parameter)  |
| `cursor`   | string  | No       | Cursor for pagination (query parameter)      |
| `limit`    | integer | No       | Number of results per page (query parameter) |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.avala.ai/api/v1/exports/" \
    -H "X-Avala-Api-Key: $AVALA_API_KEY"
  ```

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

  response = requests.get(
      "https://api.avala.ai/api/v1/exports/",
      headers={"X-Avala-Api-Key": "YOUR_API_KEY"}
  )
  exports = response.json()["results"]
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    "https://api.avala.ai/api/v1/exports/",
    {
      headers: { "X-Avala-Api-Key": "YOUR_API_KEY" },
    }
  );
  const { results } = await response.json();
  ```

  ```go Go theme={null}
  req, _ := http.NewRequest("GET", "https://api.avala.ai/api/v1/exports/", nil)
  req.Header.Set("X-Avala-Api-Key", "YOUR_API_KEY")

  resp, err := http.DefaultClient.Do(req)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "next": null,
  "previous": null,
  "results": [
    {
      "uid": "880b0700-d51e-74a7-d049-779988770000",
      "name": "Training Data Export",
      "format": "avala-json-external",
      "status": "exported",
      "total_task_count": 1000,
      "exported_task_count": 1000,
      "download_url": "https://storage.avala.ai/exports/880b0700.zip",
      "datasets": ["550e8400-e29b-41d4-a716-446655440000"],
      "slices": [],
      "projects": ["770a9600-a40d-63f6-c938-668877660000"],
      "organization": null,
      "created_at": "2025-01-21T10:00:00Z"
    }
  ]
}
```

### Fields

| Field                 | Type              | Description                                                           |
| --------------------- | ----------------- | --------------------------------------------------------------------- |
| `uid`                 | string (UUID)     | Unique identifier for the export                                      |
| `name`                | string            | Display name of the export                                            |
| `format`              | string            | Export format used                                                    |
| `status`              | string            | Current export status                                                 |
| `total_task_count`    | integer           | Total number of tasks to export                                       |
| `exported_task_count` | integer           | Number of tasks exported so far                                       |
| `download_url`        | string            | URL to download the export file (available when status is `exported`) |
| `datasets`            | array             | Array of dataset UUIDs included in the export                         |
| `slices`              | array             | Array of slice UUIDs included in the export                           |
| `projects`            | array             | Array of project UUIDs included in the export                         |
| `organization`        | object            | Associated organization, if any                                       |
| `created_at`          | string (datetime) | ISO 8601 timestamp of when the export was created                     |

***

## Create Export

```
POST /api/v1/exports/
```

Creates a new export job. Exports are processed asynchronously -- poll the List Exports endpoint to check status and retrieve the download URL when complete.

### Parameters

| Name                  | Type   | Required | Description                                 |
| --------------------- | ------ | -------- | ------------------------------------------- |
| `name`                | string | Yes      | Export name (1-255 characters)              |
| `format`              | string | Yes      | Export format (see Supported Formats below) |
| `datasets`            | array  | Yes      | Array of dataset UUIDs to export            |
| `projects`            | array  | Yes      | Array of project UUIDs to export            |
| `slices`              | array  | Yes      | Array of slice UUIDs to export              |
| `filter_query_string` | string | No       | Filter query to narrow exported results     |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.avala.ai/api/v1/exports/" \
    -H "X-Avala-Api-Key: $AVALA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "My Export",
      "format": "avala-json-external",
      "datasets": ["550e8400-e29b-41d4-a716-446655440000"],
      "projects": [],
      "slices": []
    }'
  ```

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

  response = requests.post(
      "https://api.avala.ai/api/v1/exports/",
      headers={
          "X-Avala-Api-Key": "YOUR_API_KEY",
          "Content-Type": "application/json"
      },
      json={
          "name": "My Export",
          "format": "avala-json-external",
          "datasets": ["550e8400-e29b-41d4-a716-446655440000"],
          "projects": [],
          "slices": []
      }
  )
  export = response.json()
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    "https://api.avala.ai/api/v1/exports/",
    {
      method: "POST",
      headers: {
        "X-Avala-Api-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        name: "My Export",
        format: "avala-json-external",
        datasets: ["550e8400-e29b-41d4-a716-446655440000"],
        projects: [],
        slices: [],
      }),
    }
  );
  const exportData = await response.json();
  ```

  ```go Go theme={null}
  body := strings.NewReader(`{
      "name": "My Export",
      "format": "avala-json-external",
      "datasets": ["550e8400-e29b-41d4-a716-446655440000"],
      "projects": [],
      "slices": []
  }`)

  req, _ := http.NewRequest("POST", "https://api.avala.ai/api/v1/exports/", body)
  req.Header.Set("X-Avala-Api-Key", "YOUR_API_KEY")
  req.Header.Set("Content-Type", "application/json")

  resp, err := http.DefaultClient.Do(req)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "uid": "880b0700-d51e-74a7-d049-779988770000",
  "name": "My Export",
  "format": "avala-json-external",
  "status": "requested",
  "total_task_count": null,
  "exported_task_count": null,
  "download_url": null,
  "datasets": ["550e8400-e29b-41d4-a716-446655440000"],
  "slices": [],
  "projects": [],
  "organization": null,
  "created_at": "2025-01-21T10:00:00Z"
}
```

### Fields

| Field                 | Type              | Description                              |
| --------------------- | ----------------- | ---------------------------------------- |
| `uid`                 | string (UUID)     | Unique identifier for the created export |
| `name`                | string            | Export name as provided                  |
| `format`              | string            | Export format as provided                |
| `status`              | string            | Initial status, always `requested`       |
| `total_task_count`    | integer           | `null` until processing begins           |
| `exported_task_count` | integer           | `null` until processing begins           |
| `download_url`        | string            | `null` until export completes            |
| `datasets`            | array             | Dataset UUIDs included                   |
| `slices`              | array             | Slice UUIDs included                     |
| `projects`            | array             | Project UUIDs included                   |
| `organization`        | object            | Associated organization                  |
| `created_at`          | string (datetime) | ISO 8601 timestamp of creation           |

***

## Supported Formats

| Format                | Description                                                          |
| --------------------- | -------------------------------------------------------------------- |
| `avala-json-external` | Avala's native JSON format with full metadata and annotation details |
| `coco`                | COCO format for object detection, segmentation, and keypoints        |
| `kitti`               | KITTI format for autonomous driving (2D/3D)                          |
| `pascal-voc`          | Pascal VOC (CVAT XML) format for object detection                    |
| `yolo`                | YOLO format for object detection models                              |

***

## Avala Grouped JSON Schema

The `avala-json-external` format exports all annotation data in a single structured JSON file. The top-level structure groups data by datasets, projects, and results.

### Top-Level Fields

| Field            | Type   | Description                                                               |
| ---------------- | ------ | ------------------------------------------------------------------------- |
| `scheme_version` | string | Schema version number (e.g., `"1.0"`)                                     |
| `export_info`    | object | Export metadata including name, creation timestamp, and export parameters |
| `datasets`       | array  | Array of dataset objects with their items                                 |
| `projects`       | array  | Array of project objects with their configurations and label taxonomies   |
| `results`        | array  | Array of annotation result objects containing the actual annotations      |

### Sample Structure

```json theme={null}
{
  "scheme_version": "1.0",
  "export_info": {
    "name": "Training Data Export",
    "created_at": "2025-01-21T10:00:00Z",
    "format": "avala-json-external",
    "filter_query_string": null
  },
  "datasets": [
    {
      "uid": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Highway Scenes",
      "items": [
        {
          "uid": "660f9500-f30c-52e5-b827-557766551111",
          "ref_id": "frame_001",
          "metadata": { "weather": "clear", "time": "day" }
        }
      ]
    }
  ],
  "projects": [
    {
      "uid": "770a9600-a40d-63f6-c938-668877660000",
      "name": "Object Detection",
      "labels": [
        { "name": "car", "color": "#FF0000" },
        { "name": "pedestrian", "color": "#00FF00" }
      ]
    }
  ],
  "results": [
    {
      "uid": "880b0700-d51e-74a7-d049-779988770000",
      "dataset_item_uid": "660f9500-f30c-52e5-b827-557766551111",
      "project_uid": "770a9600-a40d-63f6-c938-668877660000",
      "annotations": [
        {
          "label": "car",
          "type": "bounding_box",
          "coordinates": { "x": 100, "y": 200, "width": 150, "height": 80 },
          "attributes": { "occluded": false, "truncated": false }
        }
      ]
    }
  ]
}
```

***

## Export Statuses

| Status      | Description                                                   |
| ----------- | ------------------------------------------------------------- |
| `requested` | Export has been requested and is queued for processing        |
| `exporting` | Export is actively being processed                            |
| `exported`  | Export completed successfully and `download_url` is available |
| `failed`    | Export failed during processing                               |
| `aborted`   | Export was aborted before completion                          |

***

## Polling for Completion

Exports are processed asynchronously. After creating an export, poll the List Exports endpoint to check whether it has completed and retrieve the download URL.

<Tip>
  We recommend a polling interval of 5 seconds. The `download_url` field will be populated once the export status transitions to `exported`.
</Tip>

<CodeGroup>
  ```python Python theme={null}
  import time
  import requests

  def wait_for_export(export_uid, api_key):
      headers = {"X-Avala-Api-Key": api_key}

      while True:
          response = requests.get(
              "https://api.avala.ai/api/v1/exports/",
              headers=headers
          )
          exports = response.json()["results"]

          export = next(
              (e for e in exports if e["uid"] == export_uid),
              None
          )

          if export and export["status"] == "exported":
              return export["download_url"]
          elif export and export["status"] == "failed":
              raise Exception("Export failed")

          time.sleep(5)
  ```

  ```typescript TypeScript theme={null}
  async function waitForExport(
    exportUid: string,
    apiKey: string
  ): Promise<string> {
    while (true) {
      const response = await fetch(
        "https://api.avala.ai/api/v1/exports/",
        {
          headers: { "X-Avala-Api-Key": apiKey },
        }
      );
      const { results } = await response.json();

      const exp = results.find(
        (e: any) => e.uid === exportUid
      );

      if (exp?.status === "exported") {
        return exp.download_url;
      } else if (exp?.status === "failed") {
        throw new Error("Export failed");
      }

      await new Promise((r) => setTimeout(r, 5000));
    }
  }
  ```

  ```go Go theme={null}
  func waitForExport(exportUID, apiKey string) (string, error) {
      for {
          req, _ := http.NewRequest("GET", "https://api.avala.ai/api/v1/exports/", nil)
          req.Header.Set("X-Avala-Api-Key", apiKey)

          resp, err := http.DefaultClient.Do(req)
          if err != nil {
              return "", err
          }

          var result struct {
              Results []struct {
                  UID         string `json:"uid"`
                  Status      string `json:"status"`
                  DownloadURL string `json:"download_url"`
              } `json:"results"`
          }
          json.NewDecoder(resp.Body).Decode(&result)
          resp.Body.Close()

          for _, e := range result.Results {
              if e.UID == exportUID {
                  if e.Status == "exported" {
                      return e.DownloadURL, nil
                  } else if e.Status == "failed" {
                      return "", fmt.Errorf("export failed")
                  }
              }
          }

          time.Sleep(5 * time.Second)
      }
  }
  ```

  ```bash cURL theme={null}
  # Poll until status is "exported"
  while true; do
    STATUS=$(curl -s "https://api.avala.ai/api/v1/exports/" \
      -H "X-Avala-Api-Key: $AVALA_API_KEY" \
      | jq -r ".results[] | select(.uid == \"$EXPORT_UID\") | .status")

    if [ "$STATUS" = "exported" ]; then
      echo "Export complete. Fetching download URL..."
      curl -s "https://api.avala.ai/api/v1/exports/" \
        -H "X-Avala-Api-Key: $AVALA_API_KEY" \
        | jq -r ".results[] | select(.uid == \"$EXPORT_UID\") | .download_url"
      break
    elif [ "$STATUS" = "failed" ]; then
      echo "Export failed."
      break
    fi

    sleep 5
  done
  ```
</CodeGroup>

***

## Error Responses

### Validation Error (400)

```json theme={null}
{
  "name": ["This field is required."],
  "format": ["\"invalid\" is not a valid choice."]
}
```

Returned when the request body is missing required fields or contains invalid values.

### Unauthorized (401)

```json theme={null}
{
  "detail": "Invalid API key."
}
```

Returned when the `X-Avala-Api-Key` header is missing or contains an invalid key.

### Permission Denied (403)

```json theme={null}
{
  "detail": "You do not have permission to perform this action."
}
```

Returned when the authenticated user does not have access to the requested resources.

### Not Found (404)

```json theme={null}
{
  "detail": "Not found."
}
```

Returned when a referenced dataset, project, or slice UUID does not exist.
