Sentinel

API overview

Authenticate with an API key and call the Sentinel platform API.

The Sentinel API gives your scripts, services, and backend direct access to the same platform the dashboard uses. Read robot state, command robots, control episode recording, and query collected data.

All endpoints live under a versioned base path:

https://api-prod.avearobotics.com/v1

/v1 is additive-only. Fields and endpoints are added over time; existing ones do not change shape or disappear.

Authentication

Create an API key in the dashboard under API keys in the sidebar. Requires an org admin role. The key is shown once at creation — store it in your secret manager.

Send it as a bearer token on every request:

curl https://api-prod.avearobotics.com/v1/robots \
  -H "Authorization: Bearer ak_..."

Keys belong to your organization. Every request is scoped to the org that owns the key; there is no way to address another org's resources.

Scopes

Each key carries one or more scopes, chosen at creation:

ScopeGrants
robots:readRead robot inventory and state
robots:commandSend commands to robots and control episode recording
data:readRead episodes, datasets, and exports
data:writeUpdate episode annotations and outcomes, create datasets
fleet:readReserved for upcoming fleet endpoints
adminManage API keys and org settings

A request without the required scope fails with 403 missing_scope. Grant the narrowest scopes that work: a data-pipeline key needs data:read, not admin. A key can never mint another key with scopes its creator does not hold.

Keys can also be managed programmatically with the admin scope — POST /v1/api-keys (accepts name, scopes, and an optional expires_at), GET /v1/api-keys, and DELETE /v1/api-keys/{id} (revocation, immediate and permanent). GET /v1/entitlements reports your org's tier, feature flags, and limits.

Conventions

Bodies are snake_case JSON. Requests and responses.

Errors use one envelope. Every error response has the same shape:

{
  "error": {
    "code": "robot_offline",
    "message": "Robot is not connected.",
    "details": {}
  }
}

code is a stable string you can branch on:

CodeStatusMeaning
unauthorized401Missing credentials
invalid_credentials401The API key is malformed, revoked, or expired
missing_scope403Key lacks the required scope
feature_not_enabled403Endpoint requires a plan upgrade
org_suspended403The organization is suspended
not_found404Resource does not exist in your org
conflict409State conflict, such as snapshotting a dataset twice
response_too_large413A single row exceeds the export size cap
validation_failed422Body failed schema validation, or the robot does not support the command; see details
rate_limited429Back off and retry
internal500Unexpected server error
robot_offline503Robot is not connected to the platform
command_timeout504Robot did not acknowledge a command in time — it may still execute

Lists paginate with cursors. Pass ?limit= (1–100) and follow the cursor field in the response until it is null:

curl "https://api-prod.avearobotics.com/v1/robots?limit=50&cursor=eyJj..."

NDJSON endpoints (episode export, dataset manifests) return the continuation cursor in the X-Next-Cursor response header instead; the header is absent on the final page.

POSTs accept an Idempotency-Key header. Send a unique key with any POST; retrying with the same key and body returns the stored response instead of running the operation twice. Replays are honored for 24 hours. The same key with a different body fails with 422.

Robots are addressed by ID or name. Path parameters written {id} accept the robot's UUID (canonical, stable) or its org-unique session_name. Use the UUID in anything durable.

OpenAPI specification

The full machine-readable contract is available as openapi.json — generated from the same route definitions that serve the API.

Next steps