Create Dataset
POST /api/v1/datasets/
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the dataset |
slug | string | Yes | URL-friendly identifier |
data_type | string | Yes | Type of data: image, video, lidar, mcap, splat, or image_3d |
visibility | string | No | private or public (default: private) |
create_metadata | boolean | No | Whether to create dataset metadata (default: true) |
provider_config | object | No | Cloud storage provider configuration (see below) |
owner_name | string | No | Dataset owner username or email |
Provider Config (S3)
| Field | Type | Description |
|---|---|---|
provider | string | aws_s3 |
s3_bucket_name | string | S3 bucket name |
s3_bucket_region | string | AWS region |
s3_bucket_prefix | string | Key prefix for dataset files |
s3_access_key_id | string | AWS access key ID |
s3_secret_access_key | string | AWS secret access key |
s3_is_accelerated | boolean | Enable S3 Transfer Acceleration |
Request
curl -X POST "https://api.avala.ai/api/v1/datasets/" \
-H "X-Avala-Api-Key: $AVALA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "LiDAR Captures Q1",
"slug": "lidar-captures-q1",
"data_type": "lidar",
"visibility": "private",
"provider_config": {
"provider": "aws_s3",
"s3_bucket_name": "my-datasets",
"s3_bucket_region": "us-east-1",
"s3_bucket_prefix": "captures/q1/",
"s3_access_key_id": "AKIA...",
"s3_secret_access_key": "your-secret-key"
}
}'
from avala import Client
client = Client()
dataset = client.datasets.create(
name="LiDAR Captures Q1",
slug="lidar-captures-q1",
data_type="lidar",
visibility="private",
provider_config={
"provider": "aws_s3",
"s3_bucket_name": "my-datasets",
"s3_bucket_region": "us-east-1",
"s3_bucket_prefix": "captures/q1/",
"s3_access_key_id": "AKIA...",
"s3_secret_access_key": "your-secret-key",
},
)
print(dataset.uid)
import Avala from "@avala-ai/sdk";
const avala = new Avala();
const dataset = await avala.datasets.create({
name: "LiDAR Captures Q1",
slug: "lidar-captures-q1",
dataType: "lidar",
visibility: "private",
providerConfig: {
provider: "aws_s3",
s3_bucket_name: "my-datasets",
s3_bucket_region: "us-east-1",
s3_bucket_prefix: "captures/q1/",
s3_access_key_id: "AKIA...",
s3_secret_access_key: "your-secret-key",
},
});
console.log(dataset.uid);
avala datasets create \
--name "LiDAR Captures Q1" \
--slug lidar-captures-q1 \
--data-type lidar \
--provider-config '{"provider":"aws_s3","s3_bucket_name":"my-datasets","s3_bucket_region":"us-east-1","s3_bucket_prefix":"captures/q1/"}'
Response
{
"uid": "550e8400-e29b-41d4-a716-446655440000",
"name": "LiDAR Captures Q1",
"slug": "lidar-captures-q1",
"data_type": "lidar",
"is_sequence": true,
"visibility": "private",
"status": "creating",
"item_count": 0,
"project_count": 0,
"owner_name": "johndoe",
"size_bytes": 0,
"annotations_count": 0
}
List Datasets
GET /api/v1/datasets/{owner_name}/list/
This endpoint returns datasets owned directly by the user. Organization-owned datasets are not included — use List Organization Datasets instead.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner_name | string | Yes | Username of the dataset owner (path parameter) |
data_type | string | No | Filter by data type: image, video, lidar, mcap, splat, or image_3d (query parameter) |
name | string | No | Filter by name (case-insensitive substring match) (query parameter) |
status | string | No | Filter by dataset status (query parameter) |
visibility | string | No | Filter by visibility: public or private (query parameter) |
ordering | string | No | Field to order results by (query parameter) |
page | integer | No | Page number for pagination (query parameter) |
limit | integer | No | Number of results per page (query parameter) |
Request
curl "https://api.avala.ai/api/v1/datasets/johndoe/list/" \
-H "X-Avala-Api-Key: $AVALA_API_KEY"
import requests
response = requests.get(
"https://api.avala.ai/api/v1/datasets/johndoe/list/",
headers={"X-Avala-Api-Key": "YOUR_API_KEY"}
)
datasets = response.json()["results"]
const response = await fetch(
"https://api.avala.ai/api/v1/datasets/johndoe/list/",
{
headers: { "X-Avala-Api-Key": "YOUR_API_KEY" },
}
);
const { results } = await response.json();
req, _ := http.NewRequest("GET", "https://api.avala.ai/api/v1/datasets/johndoe/list/", nil)
req.Header.Set("X-Avala-Api-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
Response
{
"count": 25,
"next": "https://api.avala.ai/api/v1/datasets/johndoe/list/?page=2",
"previous": null,
"results": [
{
"uid": "550e8400-e29b-41d4-a716-446655440000",
"name": "Training Images",
"slug": "training-images",
"data_type": "image",
"is_sequence": false,
"visibility": "private",
"status": "created",
"item_count": 1000,
"project_count": 2,
"owner_name": "johndoe",
"size_bytes": 5368709120,
"annotations_count": 4500
}
]
}
Fields
| Field | Type | Description |
|---|---|---|
uid | string (UUID) | Unique identifier for the dataset |
name | string | Display name of the dataset |
slug | string | URL-friendly identifier |
data_type | string | Type of data in the dataset (image, video, lidar, mcap, splat, or image_3d) |
is_sequence | boolean | Whether the dataset contains sequences |
visibility | string | public or private |
status | string | Current dataset status (creating or created) |
item_count | integer | Number of items in the dataset |
project_count | integer | Number of projects associated with the dataset |
owner_name | string | Username of the dataset owner |
size_bytes | integer | Total size of the dataset in bytes |
annotations_count | integer | Total number of annotations across all items |
List Organization Datasets
GET /api/v1/organizations/{org_slug}/datasets/
If your datasets belong to an organization, use this endpoint instead of the user-scoped List Datasets endpoint.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org_slug | string | Yes | Slug identifier of the organization (path parameter) |
data_type | string | No | Filter by data type: image, video, lidar, mcap, splat, or image_3d (query parameter) |
name | string | No | Filter by name (case-insensitive substring match) (query parameter) |
status | string | No | Filter by dataset status (query parameter) |
visibility | string | No | Filter by visibility: public or private (query parameter) |
search | string | No | Search by name or slug (query parameter) |
ordering | string | No | Field to order results by (query parameter) |
page | integer | No | Page number for pagination (query parameter) |
Request
curl "https://api.avala.ai/api/v1/organizations/my-org/datasets/?data_type=lidar" \
-H "X-Avala-Api-Key: $AVALA_API_KEY"
import requests
response = requests.get(
"https://api.avala.ai/api/v1/organizations/my-org/datasets/?data_type=lidar",
headers={"X-Avala-Api-Key": "YOUR_API_KEY"}
)
datasets = response.json()["results"]
Response
Same format as List Datasets.List Sequences (Single Dataset)
GET /api/v1/datasets/{owner_name}/{dataset_slug}/sequences/
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner_name | string | Yes | Username of the dataset owner (path parameter) |
dataset_slug | string | Yes | Slug identifier of the dataset (path parameter) |
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
curl "https://api.avala.ai/api/v1/datasets/johndoe/lidar-captures/sequences/" \
-H "X-Avala-Api-Key: $AVALA_API_KEY"
import requests
response = requests.get(
"https://api.avala.ai/api/v1/datasets/johndoe/lidar-captures/sequences/",
headers={"X-Avala-Api-Key": "YOUR_API_KEY"}
)
sequences = response.json()["results"]
const response = await fetch(
"https://api.avala.ai/api/v1/datasets/johndoe/lidar-captures/sequences/",
{
headers: { "X-Avala-Api-Key": "YOUR_API_KEY" },
}
);
const { results } = await response.json();
req, _ := http.NewRequest("GET", "https://api.avala.ai/api/v1/datasets/johndoe/lidar-captures/sequences/", nil)
req.Header.Set("X-Avala-Api-Key", "YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
Response
{
"next": null,
"previous": null,
"results": [
{
"uid": "660f9500-f39c-52e5-b827-557766550000",
"key": "sequence_001",
"status": "completed",
"featured_image": "https://storage.avala.ai/sequences/seq_001/featured.jpg",
"number_of_frames": 150,
"views": [
{
"key": "camera_front",
"load": "https://storage.avala.ai/sequences/seq_001/camera_front/",
"metrics": null
}
]
}
]
}
Fields
| Field | Type | Description |
|---|---|---|
uid | string (UUID) | Unique identifier for the sequence |
key | string | Sequence key name |
status | string | Current workflow status of the sequence |
featured_image | string | URL to the featured preview image |
number_of_frames | integer | Total number of frames in the sequence |
views | array | Array of view objects, each containing key, load, and metrics |
List Sequences (Cross-Dataset)
GET /api/v1/datasets/{owner_name}/sequences/
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner_name | string | Yes | Username of the dataset owner (path parameter) |
status | string | No | Filter by sequence status (query parameter) |
status__in | string | No | Comma-separated list of statuses to filter by (query parameter) |
dataset__slug | string | No | Filter sequences by a single dataset slug (query parameter) |
dataset__slug__in | string | No | Comma-separated list of dataset slugs to filter by (query parameter) |
page | integer | No | Page number for pagination (query parameter) |
Request
# Get sequences for specific batches
curl "https://api.avala.ai/api/v1/datasets/johndoe/sequences/?dataset__slug__in=batch-001,batch-002,batch-003" \
-H "X-Avala-Api-Key: $AVALA_API_KEY"
# Filter by status
curl "https://api.avala.ai/api/v1/datasets/johndoe/sequences/?status__in=customer_review,rework_requested" \
-H "X-Avala-Api-Key: $AVALA_API_KEY"
# Combine filters
curl "https://api.avala.ai/api/v1/datasets/johndoe/sequences/?dataset__slug__in=batch-001,batch-002&status=customer_approved" \
-H "X-Avala-Api-Key: $AVALA_API_KEY"
import requests
# Bulk QC status check for multiple batches
batch_slugs = "batch-001,batch-002,batch-003"
response = requests.get(
f"https://api.avala.ai/api/v1/datasets/johndoe/sequences/?dataset__slug__in={batch_slugs}",
headers={"X-Avala-Api-Key": "YOUR_API_KEY"}
)
sequences = response.json()["results"]
# Group by dataset
from collections import defaultdict
by_dataset = defaultdict(list)
for seq in sequences:
by_dataset[seq["dataset"]["slug"]].append(seq)
Use this endpoint instead of making separate calls to
/datasets/{owner}/{slug}/sequences/ for each dataset. This avoids rate limiting when checking QC status across many batches.Dataset Health
GET /api/v1/datasets/{owner_name}/{dataset_slug}/health/
Read-only ingest and indexing snapshot for a dataset. Designed for programmatic validation after upload: confirm frame totals, sequence counts, and calibration presence without opening Mission Control.
Request
curl https://api.avala.ai/api/v1/datasets/acme-corp/highway-mcap/health/ \
-H "X-Avala-Api-Key: YOUR_API_KEY"
Response
{
"dataset_uid": "123e4567-e89b-12d3-a456-426614174000",
"dataset_slug": "highway-mcap",
"dataset_status": "created",
"item_count": 569,
"sequence_count": 1,
"total_frames": 569,
"s3_prefix": "datasets/highway-mcap/full-scene-569",
"gc_storage_prefix": null,
"last_updated_at": "2026-04-21T15:33:02Z",
"sequences": [
{
"uid": "55555555-5555-5555-5555-555555555555",
"key": "full-scene-569",
"status": "completed",
"frame_count": 569,
"has_lidar_calibration": true,
"has_camera_calibration": true
}
],
"ingest_ok": true,
"issues": []
}
Fields
| Field | Description |
|---|---|
dataset_uid | Dataset UUID |
dataset_slug | Dataset slug |
dataset_status | creating or created |
item_count | Total items (stored on the dataset row) |
sequence_count | Number of sequences attached |
total_frames | Sum of frames across sequences |
s3_prefix | Configured S3 prefix. Owner/staff only — returns null for non-owners, even on public datasets |
gc_storage_prefix | Configured GCS prefix. Owner/staff only — returns null for non-owners |
last_updated_at | Dataset row’s last-update timestamp |
sequences[].frame_count | Frames per sequence |
sequences[].has_lidar_calibration | Whether the first frame carries metadata.lidar_metadata.calibration_data |
sequences[].has_camera_calibration | Whether the dataset carries metadata.camera_calibration |
ingest_ok | true when no issues were detected |
issues | Human-readable diagnostics — empty when ingest_ok is true |
created status, empty dataset, sequences with zero frames.
Data Types
| Type | Description |
|---|---|
image | Single images (JPEG, PNG, WebP, BMP) |
video | Video files converted to frame sequences |
lidar | Point cloud data (PCD, PLY) |
mcap | MCAP files with sensor data |
splat | Gaussian Splat 3D scene reconstructions |
image_3d | 3D image data |
Dataset Status
| Status | Description |
|---|---|
creating | Dataset is being created and is not yet ready |
created | Dataset has been created and is ready for use |
Sequence Status Values
Sequences progress through various workflow statuses during the annotation lifecycle.| Status | Description |
|---|---|
unattempted | Not yet started |
pending | Awaiting processing |
completed | Fully annotated and reviewed |
rework_required | Needs corrections |
ready_for_annotation | Ready to be annotated |
labeling_4d | 3D/4D annotation in progress |
review_4d | 3D/4D annotation review in progress |
ready_for_2d | Ready for 2D annotation |
labeling_2d | 2D annotation in progress |
review_2d | 2D annotation review in progress |
final_review | Final quality control review |
customer_approved | Approved by the customer |
Error Responses
Not Found (404)
{
"detail": "Not found."
}
Permission Denied (403)
{
"detail": "You do not have permission to perform this action."
}
Unauthorized (401)
{
"detail": "Invalid API key."
}
X-Avala-Api-Key header is missing or contains an invalid key.