The Fleet API is in preview. Endpoints described on this page may change.
Base URL
All Fleet API requests use the standard Avala API base URL:https://api.avala.ai/api/v1/fleet
X-Avala-Api-Key header. See Authentication for details on creating and managing keys.
Devices
Register, list, and manage devices in your fleet.List Devices
GET /api/v1/fleet/devices/
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by device status: online, offline, maintenance |
type | string | Filter by device type (e.g., manipulator, amr, vehicle) |
tags | string | Comma-separated tag filter |
metadata | string | JSON-encoded metadata filter (e.g., {"location": "warehouse-1"}) |
limit | integer | Results per page (default: 50, max: 200) |
cursor | string | Pagination cursor |
curl "https://api.avala.ai/api/v1/fleet/devices/?status=online" \
-H "X-Avala-Api-Key: avk_your_api_key"
from avala import Client
client = Client(api_key="your-api-key")
devices = client.fleet.devices.list(status="online")
for device in devices:
print(device.name, device.status)
import Avala from "@avala-ai/sdk";
const avala = new Avala({ apiKey: "your-api-key" });
const devices = await avala.fleet.devices.list({ status: "online" });
for (const device of devices.items) {
console.log(device.name, device.status);
}
{
"next": "https://api.avala.ai/api/v1/fleet/devices/?cursor=eyJpZCI6MTB9",
"previous": null,
"results": [
{
"uid": "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "robot-alpha-01",
"type": "amr",
"status": "online",
"tags": ["warehouse", "floor-2"],
"last_seen_at": "2026-02-26T14:30:00Z",
"firmware_version": "2.4.1",
"metadata": {
"model": "AMR-500",
"location": "Building A"
},
"created_at": "2025-11-01T08:00:00Z",
"updated_at": "2026-02-26T14:30:00Z"
}
]
}
Register Device
POST /api/v1/fleet/devices/
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable device name |
type | string | No | Device type (e.g., manipulator, amr, drone) |
firmware_version | string | No | Current firmware version |
tags | array | No | Tags for organizing devices |
metadata | object | No | Arbitrary key-value metadata |
curl -X POST "https://api.avala.ai/api/v1/fleet/devices/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "robot-alpha-02",
"tags": ["warehouse", "floor-1"],
"metadata": {
"model": "AMR-500",
"location": "Building A"
}
}'
device = client.fleet.devices.register(
name="robot-alpha-02",
tags=["warehouse", "floor-1"],
metadata={"model": "AMR-500", "location": "Building A"},
)
print(device.uid)
const device = await avala.fleet.devices.register({
name: "robot-alpha-02",
tags: ["warehouse", "floor-1"],
metadata: { model: "AMR-500", location: "Building A" },
});
console.log(device.uid);
201 Created
{
"uid": "dev_f7e8d9c0-b1a2-3456-cdef-789012345678",
"name": "robot-alpha-02",
"status": "offline",
"tags": ["warehouse", "floor-1"],
"last_seen_at": null,
"firmware_version": null,
"metadata": {
"model": "AMR-500",
"location": "Building A"
},
"device_token": "dtk_abc123def456...",
"created_at": "2026-02-26T15:00:00Z",
"updated_at": "2026-02-26T15:00:00Z"
}
The
device_token is returned only in the create response. Store it securely — it cannot be retrieved again. The device uses this token to authenticate when uploading recordings.Get Device
GET /api/v1/fleet/devices/{uid}/
curl "https://api.avala.ai/api/v1/fleet/devices/dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "X-Avala-Api-Key: avk_your_api_key"
device = client.fleet.devices.get("dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890")
const device = await avala.fleet.devices.get("dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890");
Update Device
PATCH /api/v1/fleet/devices/{uid}/
| Field | Type | Description |
|---|---|---|
name | string | Updated device name |
status | string | Device status: online, offline, maintenance |
firmware_version | string | Current firmware version |
tags | array | Replacement tags (replaces all existing tags) |
metadata | object | Replacement metadata (merged with existing) |
curl -X PATCH "https://api.avala.ai/api/v1/fleet/devices/dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"tags": ["warehouse", "floor-3"]}'
device = client.fleet.devices.update(
device_id="dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
tags=["warehouse", "floor-3"],
)
const device = await avala.fleet.devices.update({
deviceId: "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
tags: ["warehouse", "floor-3"],
});
Deregister Device
DELETE /api/v1/fleet/devices/{uid}/
curl -X DELETE "https://api.avala.ai/api/v1/fleet/devices/dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "X-Avala-Api-Key: avk_your_api_key"
client.fleet.devices.deregister(device_id="dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890")
await avala.fleet.devices.deregister({ deviceId: "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890" });
204 No Content
Device Fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique device identifier |
name | string | Human-readable name |
type | string | Device type (e.g., manipulator, amr, drone) |
status | string | online, offline, or maintenance |
tags | array | Organization tags |
last_seen_at | string (ISO 8601) | Last heartbeat timestamp |
firmware_version | string | Reported firmware version |
metadata | object | Arbitrary key-value metadata |
created_at | string (ISO 8601) | Registration timestamp |
updated_at | string (ISO 8601) | Last update timestamp |
Recordings
List, filter, and manage recordings uploaded by fleet devices.List Recordings
GET /api/v1/fleet/recordings/
| Parameter | Type | Description |
|---|---|---|
device_id | string | Filter by device UID |
status | string | Filter by status: uploading, processing, ready, error, archived |
since | string (ISO 8601) | Return recordings created after this timestamp |
until | string (ISO 8601) | Return recordings created before this timestamp |
tags | string | Comma-separated tag filter |
limit | integer | Results per page (default: 50, max: 200) |
cursor | string | Pagination cursor |
curl "https://api.avala.ai/api/v1/fleet/recordings/?device_id=dev_a1b2c3d4&status=ready&since=2026-02-01T00:00:00Z" \
-H "X-Avala-Api-Key: avk_your_api_key"
recordings = client.fleet.recordings.list(
device_id="dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
status="ready",
since="2026-02-01T00:00:00Z",
)
const recordings = await avala.fleet.recordings.list({
deviceId: "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
status: "ready",
since: "2026-02-01T00:00:00Z",
});
{
"next": null,
"previous": null,
"results": [
{
"uid": "rec_11223344-5566-7788-99aa-bbccddeeff00",
"device_id": "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"device_name": "robot-alpha-01",
"status": "ready",
"duration_seconds": 342.5,
"size_bytes": 1073741824,
"topic_count": 12,
"tags": ["mission-47", "outdoor"],
"started_at": "2026-02-26T10:00:00Z",
"ended_at": "2026-02-26T10:05:42Z",
"created_at": "2026-02-26T10:06:00Z"
}
]
}
Get Recording
GET /api/v1/fleet/recordings/{uid}/
curl "https://api.avala.ai/api/v1/fleet/recordings/rec_11223344-5566-7788-99aa-bbccddeeff00/" \
-H "X-Avala-Api-Key: avk_your_api_key"
recording = client.fleet.recordings.get("rec_11223344-5566-7788-99aa-bbccddeeff00")
const recording = await avala.fleet.recordings.get("rec_11223344-5566-7788-99aa-bbccddeeff00");
{
"uid": "rec_11223344-5566-7788-99aa-bbccddeeff00",
"device_id": "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"device_name": "robot-alpha-01",
"status": "ready",
"duration_seconds": 342.5,
"size_bytes": 1073741824,
"topic_count": 12,
"tags": ["mission-47", "outdoor"],
"topics": [
{
"name": "/camera/front/image",
"schema": "sensor_msgs/Image",
"message_count": 3425,
"frequency_hz": 10.0
},
{
"name": "/lidar/points",
"schema": "sensor_msgs/PointCloud2",
"message_count": 3425,
"frequency_hz": 10.0
}
],
"started_at": "2026-02-26T10:00:00Z",
"ended_at": "2026-02-26T10:05:42Z",
"created_at": "2026-02-26T10:06:00Z"
}
Update Recording
PATCH /api/v1/fleet/recordings/{uid}/
| Field | Type | Description |
|---|---|---|
tags | array | Replacement tags |
status | string | Set to archived to archive the recording |
curl -X PATCH "https://api.avala.ai/api/v1/fleet/recordings/rec_11223344-5566-7788-99aa-bbccddeeff00/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"tags": ["mission-47", "outdoor", "reviewed"]}'
recording = client.fleet.recordings.update(
recording_id="rec_11223344-5566-7788-99aa-bbccddeeff00",
tags=["mission-47", "outdoor", "reviewed"],
)
const recording = await avala.fleet.recordings.update({
recordingId: "rec_11223344-5566-7788-99aa-bbccddeeff00",
tags: ["mission-47", "outdoor", "reviewed"],
});
Delete Recording
DELETE /api/v1/fleet/recordings/{uid}/
This action is irreversible. All recording data, events, and associated files are permanently removed.
curl -X DELETE "https://api.avala.ai/api/v1/fleet/recordings/rec_11223344-5566-7788-99aa-bbccddeeff00/" \
-H "X-Avala-Api-Key: avk_your_api_key"
client.fleet.recordings.delete("rec_11223344-5566-7788-99aa-bbccddeeff00")
await avala.fleet.recordings.delete("rec_11223344-5566-7788-99aa-bbccddeeff00");
204 No Content
Recording Fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique recording identifier |
device_id | string | UID of the device that created the recording |
device_name | string | Human-readable device name |
status | string | uploading, processing, ready, error, or archived |
duration_seconds | number | Recording duration in seconds |
size_bytes | integer | Total file size in bytes |
topic_count | integer | Number of topics in the recording |
tags | array | Organization tags |
topics | array | Topic details (only in detail endpoint) |
started_at | string (ISO 8601) | Recording start timestamp |
ended_at | string (ISO 8601) | Recording end timestamp |
created_at | string (ISO 8601) | Upload timestamp |
Events
Create and query timeline events associated with recordings.List Events
GET /api/v1/fleet/events/
| Parameter | Type | Description |
|---|---|---|
recording_id | string | Filter by recording UID |
device_id | string | Filter by device UID |
type | string | Filter by event type: error, warning, info, state_change, anomaly, custom |
severity | string | Filter by severity: info, warning, error, critical |
since | string (ISO 8601) | Return events after this timestamp |
until | string (ISO 8601) | Return events before this timestamp |
order_by | string | Sort order: timestamp (ascending) or -timestamp (descending, default) |
metadata_filter | string | JSON-encoded metadata query (e.g., {"motor_id": "joint_3"}) |
tags | string | Comma-separated tag filter |
limit | integer | Results per page (default: 50, max: 200) |
cursor | string | Pagination cursor |
curl "https://api.avala.ai/api/v1/fleet/events/?recording_id=rec_11223344&severity=error" \
-H "X-Avala-Api-Key: avk_your_api_key"
events = client.fleet.events.list(
recording_id="rec_11223344-5566-7788-99aa-bbccddeeff00",
severity="error",
)
const events = await avala.fleet.events.list({
recordingId: "rec_11223344-5566-7788-99aa-bbccddeeff00",
severity: "error",
});
{
"next": null,
"previous": null,
"results": [
{
"uid": "evt_aabbccdd-eeff-0011-2233-445566778899",
"recording_id": "rec_11223344-5566-7788-99aa-bbccddeeff00",
"device_id": "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "anomaly",
"label": "LiDAR topic /lidar/points dropped 15 messages in 2s window",
"severity": "error",
"timestamp": "2026-02-26T10:03:22Z",
"metadata": {
"topic": "/lidar/points",
"dropped_count": 15,
"window_seconds": 2
},
"created_at": "2026-02-26T10:03:22Z"
}
]
}
Create Event
POST /api/v1/fleet/events/
| Field | Type | Required | Description |
|---|---|---|---|
recording_id | string | Yes | Recording to associate the event with |
type | string | Yes | error, warning, info, state_change, anomaly, or custom |
label | string | Yes | Human-readable event label |
timestamp | string (ISO 8601) | Yes | When the event occurred |
description | string | No | Detailed description of the event |
duration_ms | number | No | Duration of the event in milliseconds (for span-like events) |
tags | array | No | Tags for categorizing the event |
metadata | object | No | Arbitrary event metadata |
severity | string | No | Override severity: info, warning, error, critical. Defaults based on type. |
curl -X POST "https://api.avala.ai/api/v1/fleet/events/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recording_id": "rec_11223344-5566-7788-99aa-bbccddeeff00",
"type": "anomaly",
"label": "CPU usage exceeded 90% threshold",
"timestamp": "2026-02-26T10:02:15Z",
"metadata": {
"cpu_percent": 93.2,
"threshold": 90
}
}'
event = client.fleet.events.create(
recording_id="rec_11223344-5566-7788-99aa-bbccddeeff00",
type="anomaly",
label="CPU usage exceeded 90% threshold",
timestamp="2026-02-26T10:02:15Z",
metadata={"cpu_percent": 93.2, "threshold": 90},
)
const event = await avala.fleet.events.create({
recordingId: "rec_11223344-5566-7788-99aa-bbccddeeff00",
type: "anomaly",
label: "CPU usage exceeded 90% threshold",
timestamp: "2026-02-26T10:02:15Z",
metadata: { cpu_percent: 93.2, threshold: 90 },
});
201 Created
Batch Create Events
POST /api/v1/fleet/events/batch/
| Field | Type | Required | Description |
|---|---|---|---|
recording_id | string | Yes | Recording to attach events to |
events | array | Yes | Array of event objects (max 1,000) |
POST /api/v1/fleet/events/ (excluding recording_id, which is set at the top level).
curl -X POST "https://api.avala.ai/api/v1/fleet/events/batch/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"recording_id": "rec_11223344-5566-7788-99aa-bbccddeeff00",
"events": [
{"timestamp": "2026-02-26T10:02:15Z", "type": "error", "label": "Motor overtemp"},
{"timestamp": "2026-02-26T10:02:20Z", "type": "state_change", "label": "Emergency stop"}
]
}'
events = client.fleet.events.create_batch(
recording_id="rec_11223344-5566-7788-99aa-bbccddeeff00",
events=[
{"timestamp": "2026-02-26T10:02:15Z", "type": "error", "label": "Motor overtemp"},
{"timestamp": "2026-02-26T10:02:20Z", "type": "state_change", "label": "Emergency stop"},
],
)
const result = await avala.fleet.events.createBatch({
recordingId: "rec_11223344-5566-7788-99aa-bbccddeeff00",
events: [
{ timestamp: "2026-02-26T10:02:15Z", type: "error", label: "Motor overtemp" },
{ timestamp: "2026-02-26T10:02:20Z", type: "state_change", label: "Emergency stop" },
],
});
201 Created — Returns the array of created event objects.
Get Event
GET /api/v1/fleet/events/{uid}/
Delete Event
DELETE /api/v1/fleet/events/{uid}/
204 No Content
Event Fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique event identifier |
recording_id | string | Associated recording UID |
device_id | string | Device that generated the event (derived from recording) |
type | string | error, warning, info, state_change, anomaly, or custom |
label | string | Human-readable event label |
description | string | Detailed event description |
timestamp | string (ISO 8601) | When the event occurred |
duration_ms | number | Event duration in milliseconds (nullable) |
tags | array | Event tags |
metadata | object | Arbitrary metadata |
severity | string | info, warning, error, or critical |
created_at | string (ISO 8601) | Server-side creation timestamp |
Rules
Recording rules define conditions that automatically trigger events, flag recordings, or start processing pipelines.List Rules
GET /api/v1/fleet/rules/
curl "https://api.avala.ai/api/v1/fleet/rules/" \
-H "X-Avala-Api-Key: avk_your_api_key"
rules = client.fleet.rules.list()
# Filter by enabled status or condition type
rules = client.fleet.rules.list(enabled=True)
rules = client.fleet.rules.list(condition_type="threshold")
let rules = await avala.fleet.rules.list();
// Filter by enabled status or condition type
rules = await avala.fleet.rules.list({ enabled: true });
rules = await avala.fleet.rules.list({ conditionType: "threshold" });
| Parameter | Type | Description |
|---|---|---|
enabled | boolean | Filter by enabled/disabled status. |
condition_type | string | Filter by condition type (threshold, pattern, frequency, absence, composite). |
{
"next": null,
"previous": null,
"results": [
{
"uid": "rul_00112233-4455-6677-8899-aabbccddeeff",
"name": "Flag high CPU recordings",
"description": "Flag any recording where CPU exceeds 90% for more than 10 seconds",
"enabled": true,
"condition": {
"type": "threshold",
"topic": "/diagnostics/cpu",
"field": "data.aggregate_percent",
"operator": "gt",
"value": 90,
"window": "10s"
},
"actions": [
{
"type": "tag",
"value": "high-cpu"
},
{
"type": "create_event",
"event_type": "warning",
"label": "CPU exceeded 90% for >10s"
}
],
"scope": null,
"hit_count": 42,
"last_hit_at": "2026-02-25T18:45:00Z",
"created_at": "2026-01-15T09:00:00Z",
"updated_at": "2026-02-20T11:30:00Z"
}
]
}
Create Rule
POST /api/v1/fleet/rules/
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable rule name |
description | string | No | Description of the rule’s purpose |
enabled | boolean | No | Whether the rule is active (default: true) |
condition | object | Yes | Trigger condition (see below) |
actions | array | Yes | Actions to execute when the condition is met |
scope | object | No | Limit rule to specific devices or groups. Contains device_ids and/or group_ids arrays. |
| Type | Description | Required Fields |
|---|---|---|
threshold | Fires when a topic field exceeds a value | topic, field, operator, value, optional window |
pattern | Fires when a topic field matches a regex pattern | topic, field, regex |
frequency | Fires when event count crosses a threshold in a time window | topic, count_operator, count, window |
absence | Fires when expected data is missing for a duration | topic, timeout |
composite | Logical combination of other conditions | operator (and or or), conditions |
| Type | Description | Required Fields |
|---|---|---|
tag | Add a tag to the recording | value |
create_event | Create a timeline event | event_type, label, optional severity |
flag_for_review | Flag the recording for manual review | — |
notify | Send notification to an alert channel | channel_id |
auto_label | Trigger an auto-labeling pipeline | pipeline_id |
curl -X POST "https://api.avala.ai/api/v1/fleet/rules/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "LiDAR dropout detection",
"description": "Detect when LiDAR data is missing for more than 2 seconds",
"condition": {
"type": "absence",
"topic": "/lidar/points",
"timeout": "2s"
},
"actions": [
{"type": "create_event", "event_type": "error", "label": "LiDAR data missing for >2s"},
{"type": "tag", "value": "lidar-dropout"},
{"type": "notify", "channel_id": "ch_aabb1122"}
]
}'
rule = client.fleet.rules.create(
name="LiDAR dropout detection",
description="Detect when LiDAR data is missing for more than 2 seconds",
condition={
"type": "absence",
"topic": "/lidar/points",
"timeout": "2s",
},
actions=[
{"type": "create_event", "event_type": "error", "label": "LiDAR data missing for >2s"},
{"type": "tag", "value": "lidar-dropout"},
{"type": "notify", "channel_id": "ch_aabb1122"},
],
)
const rule = await avala.fleet.rules.create({
name: "LiDAR dropout detection",
description: "Detect when LiDAR data is missing for more than 2 seconds",
condition: {
type: "absence",
topic: "/lidar/points",
timeout: "2s",
},
actions: [
{ type: "create_event", eventType: "error", label: "LiDAR data missing for >2s" },
{ type: "tag", value: "lidar-dropout" },
{ type: "notify", channelId: "ch_aabb1122" },
],
});
201 Created
Get Rule
GET /api/v1/fleet/rules/{uid}/
Update Rule
PATCH /api/v1/fleet/rules/{uid}/
| Field | Type | Description |
|---|---|---|
name | string | Updated rule name |
description | string | Updated description |
enabled | boolean | Set to false to disable the rule, true to re-enable |
condition | object | Updated trigger condition |
actions | array | Updated list of actions |
Delete Rule
DELETE /api/v1/fleet/rules/{uid}/
204 No Content
Rule Fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique rule identifier |
name | string | Human-readable name |
description | string | Rule description |
enabled | boolean | Whether the rule is active |
condition | object | Trigger condition |
actions | array | Actions to execute |
scope | object | Restricts rule to specific devices, groups, or tags (nullable) |
hit_count | integer | Total number of times the rule has triggered |
last_hit_at | string (ISO 8601) | When the rule last triggered (nullable) |
created_at | string (ISO 8601) | Creation timestamp |
updated_at | string (ISO 8601) | Last update timestamp |
Alerts
View and manage alerts generated by recording rules and diagnostics thresholds.List Alerts
GET /api/v1/fleet/alerts/
| Parameter | Type | Description |
|---|---|---|
device_id | string | Filter by device UID |
recording_id | string | Filter by recording UID |
rule_id | string | Filter by rule UID |
channel_id | string | Filter by notification channel UID |
status | string | Filter by status: open, acknowledged, resolved |
severity | string | Filter by severity: info, warning, error, critical |
since | string (ISO 8601) | Return alerts created after this timestamp |
until | string (ISO 8601) | Return alerts created before this timestamp |
limit | integer | Results per page (default: 50, max: 200) |
cursor | string | Pagination cursor |
curl "https://api.avala.ai/api/v1/fleet/alerts/?status=open&severity=error" \
-H "X-Avala-Api-Key: avk_your_api_key"
alerts = client.fleet.alerts.list(status="open", severity="error")
const alerts = await avala.fleet.alerts.list({ status: "open", severity: "error" });
{
"next": null,
"previous": null,
"results": [
{
"uid": "alt_99887766-5544-3322-1100-ffeeddccbbaa",
"rule_id": "rul_00112233-4455-6677-8899-aabbccddeeff",
"rule_name": "LiDAR dropout detection",
"device_id": "dev_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"device_name": "robot-alpha-01",
"recording_id": "rec_11223344-5566-7788-99aa-bbccddeeff00",
"severity": "error",
"status": "open",
"message": "LiDAR frequency dropped below 8 Hz",
"triggered_at": "2026-02-26T10:03:22Z",
"acknowledged_at": null,
"resolved_at": null,
"created_at": "2026-02-26T10:03:22Z"
}
]
}
Get Alert
GET /api/v1/fleet/alerts/{uid}/
Acknowledge Alert
POST /api/v1/fleet/alerts/{uid}/acknowledge/
curl -X POST "https://api.avala.ai/api/v1/fleet/alerts/alt_99887766-5544-3322-1100-ffeeddccbbaa/acknowledge/" \
-H "X-Avala-Api-Key: avk_your_api_key"
client.fleet.alerts.acknowledge(
alert_id="alt_99887766-5544-3322-1100-ffeeddccbbaa",
note="Investigating the issue"
)
await avala.fleet.alerts.acknowledge({
alertId: "alt_99887766-5544-3322-1100-ffeeddccbbaa",
note: "Investigating the issue",
});
{
"uid": "alt_99887766-5544-3322-1100-ffeeddccbbaa",
"status": "acknowledged",
"acknowledged_at": "2026-02-26T10:15:00Z",
"acknowledged_by": "johndoe"
}
Resolve Alert
POST /api/v1/fleet/alerts/{uid}/resolve/
| Field | Type | Required | Description |
|---|---|---|---|
note | string | No | Resolution note describing what was done |
curl -X POST "https://api.avala.ai/api/v1/fleet/alerts/alt_99887766-5544-3322-1100-ffeeddccbbaa/resolve/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"note": "LiDAR sensor recalibrated and firmware updated to v2.4.2"}'
client.fleet.alerts.resolve(
alert_id="alt_99887766-5544-3322-1100-ffeeddccbbaa",
note="LiDAR sensor recalibrated and firmware updated to v2.4.2",
)
await avala.fleet.alerts.resolve({
alertId: "alt_99887766-5544-3322-1100-ffeeddccbbaa",
note: "LiDAR sensor recalibrated and firmware updated to v2.4.2",
});
Alert Fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique alert identifier |
rule_id | string | Rule that triggered the alert |
rule_name | string | Human-readable rule name |
device_id | string | Device associated with the alert |
device_name | string | Human-readable device name |
recording_id | string | Recording associated with the alert (nullable) |
severity | string | info, warning, error, or critical |
status | string | open, acknowledged, or resolved |
message | string | Alert description |
triggered_at | string (ISO 8601) | When the alert condition was met |
acknowledged_at | string (ISO 8601) | When the alert was acknowledged (nullable) |
acknowledged_by | string | User who acknowledged the alert (nullable) |
resolved_at | string (ISO 8601) | When the alert was resolved (nullable) |
duration | string | Computed time between triggered_at and resolved_at (nullable) |
created_at | string (ISO 8601) | Server-side creation timestamp |
Alert Channels
Configure notification destinations for alerts.List Channels
GET /api/v1/fleet/alerts/channels/
curl "https://api.avala.ai/api/v1/fleet/alerts/channels/" \
-H "X-Avala-Api-Key: avk_your_api_key"
channels = client.fleet.alerts.channels.list()
const channels = await avala.fleet.alerts.channels.list();
{
"next": null,
"previous": null,
"results": [
{
"uid": "ch_aabb1122-3344-5566-7788-99aabbccddee",
"name": "Engineering Slack",
"type": "slack",
"config": {
"webhook_url": "https://hooks.slack.com/services/..."
},
"created_at": "2026-01-10T08:00:00Z"
},
{
"uid": "ch_ffeeddcc-bbaa-9988-7766-554433221100",
"name": "Ops Team Email",
"type": "email",
"config": {
"recipients": ["ops@example.com"]
},
"created_at": "2026-01-10T08:30:00Z"
}
]
}
Create Channel
POST /api/v1/fleet/alerts/channels/
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Channel display name |
type | string | Yes | Channel type: slack, email, or webhook |
config | object | Yes | Channel-specific configuration (see below) |
| Type | Config Fields |
|---|---|
slack | webhook_url (required) — Slack incoming webhook URL; channel — Optional channel override; username — Optional display name; icon_emoji — Optional emoji icon |
email | recipients (required) — Array of email addresses; subject_prefix — Optional email subject prefix |
webhook | url (required) — HTTP endpoint URL; signing_secret — Optional HMAC signing secret; headers — Optional custom headers |
curl -X POST "https://api.avala.ai/api/v1/fleet/alerts/channels/" \
-H "X-Avala-Api-Key: avk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering Slack",
"type": "slack",
"config": {
"webhook_url": "https://hooks.slack.com/services/T00/B00/xxx"
}
}'
channel = client.fleet.alerts.channels.create(
name="Engineering Slack",
type="slack",
config={"webhook_url": "https://hooks.slack.com/services/T00/B00/xxx"},
)
const channel = await avala.fleet.alerts.channels.create({
name: "Engineering Slack",
type: "slack",
config: { webhook_url: "https://hooks.slack.com/services/T00/B00/xxx" },
});
201 Created
Delete Channel
DELETE /api/v1/fleet/alerts/channels/{uid}/
Deleting a channel that is referenced by active rules does not delete the rules. The rules continue to function, but the
notify action is skipped for the deleted channel.204 No Content
Channel Fields
| Field | Type | Description |
|---|---|---|
uid | string | Unique channel identifier |
name | string | Display name |
type | string | slack, email, or webhook |
config | object | Channel-specific configuration |
created_at | string (ISO 8601) | Creation timestamp |
Common Patterns
Pagination
All list endpoints use cursor-based pagination. Follow thenext URL until it returns null to retrieve all results.
{
"next": "https://api.avala.ai/api/v1/fleet/devices/?cursor=eyJpZCI6MTB9",
"previous": null,
"results": [...]
}
limit parameter to control page size. The maximum is 200 results per page.
Error Responses
The Fleet API uses standard Avala error responses. See Error Codes for the full reference.| Status | Description |
|---|---|
400 | Bad Request — invalid or missing fields |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — insufficient permissions |
404 | Not Found — resource does not exist |
409 | Conflict — resource already exists (e.g., duplicate device name) |
429 | Too Many Requests — rate limit exceeded |
Rate Limits
Fleet API endpoints share the standard Avala rate limits. See Rate Limits for details.Additional SDK Resources
The following fleet features are available through the Python and TypeScript SDKs. REST endpoint documentation will be added as these features stabilize.| Resource | Description | Guide |
|---|---|---|
| Device Groups | Organize devices into logical groups for scoped rules and metrics | Fleet Dashboard |
| Fleet Metrics | Aggregate fleet statistics and time-series telemetry | Fleet Dashboard |
| Escalation Policies | Define multi-stage alert escalation workflows | Alerts & Notifications |
| Alert Muting & Snoozing | Suppress alerts during maintenance windows | Alerts & Notifications |
Next Steps
Fleet Dashboard
Monitor your fleet visually with the Mission Control dashboard.
Python SDK
Use the Python SDK for programmatic fleet management.
TypeScript SDK
Use the TypeScript SDK for Node.js and browser integrations.