REST API

Overview

Analog Cloud exposes a versioned REST API under /api/v1. The API is the single mode of interaction with the system: both AnalogCloudClient and the analogcli package go through it. Because the API is described by an OpenAPI-compatible specification (linked below), third-party clients can interface with Analog Cloud just as easily.

Live documentation

The deployed server serves the OpenAPI UI at /api/docs (Swagger UI) and /api/redoc (ReDoc). For anabrid's production deployment of Analog Cloud, this is reachable at https://redac.anabrid.com/api/docs.

Authentication

Every request to /api/v1/* must carry a Bearer token:

Authorization: Bearer <api_key>

Missing, disabled, or unknown keys are answered with 403 Forbidden. For run-task creation, the server additionally checks device access for the user (403 on denial) and hourly / daily rate limits for the device class (429 when exceeded). Limits are set by operators in the auth.yml file — contact your operator if you need to bump your limits.

Endpoint groups

For more detailed information and data types, please refer to the API documentation linked above.

Prefix Purpose
/api/v1/system Deployment identity and uptime.
/api/v1/users Authenticated user's profile and remaining quota.
/api/v1/devices Registered devices and their cached entity blobs.
/api/v1/tasks Compile and run tasks: creation, listing, status, logs, results, cancel, delete.

/system

Method Path Description
GET /api/v1/system/status Domain, version, uptime (seconds since server start).

/users

Method Path Description
GET /api/v1/users/me Profile (name, email, subscription, device whitelist), per-device-class rate-limit status, and the key's scheduling priority (higher ⇒ tasks served sooner; baseline is 1).

/devices

Method Path Description
GET /api/v1/devices List registered devices with name, type, availability, queue length.
GET /api/v1/devices/{device_name}/entity Retrieves the entity specification as binary blob. Can be used with pyredacc to configure the SIMULATOR and to analyze the structure of the hardware.

/tasks

Method Path Description
POST /api/v1/tasks/compile Create a compile task for devices (except SIMULATOR-type devices) which creates a circuit description from a system of ODEs.
POST /api/v1/tasks/run Given a manually-created (via pybrid) or compiled circuit, run it on one device. Since a hardware description is embedded in every circuit, users may also point it to SIMULATOR devices in order to get a mathematical simulation of the circuit.
GET /api/v1/tasks List the caller's own tasks (identified via its API key), newest-first by creation time, with their states.
POST /api/v1/tasks/search Search your own tasks with filters and pagination. See Task search.
GET /api/v1/tasks/{task_id} Returns details on a task given its ID. Returns 404 for a task the caller does not own.
GET /api/v1/tasks/{task_id}/status Current state plus full state history given a task ID.
GET /api/v1/tasks/{task_id}/log Retrieve log generated by a task, e.g., from the compiler executable.
GET /api/v1/tasks/{task_id}/result Download task's result. application/octet-stream (APB binary) for compile, application/json (nested measurement list) for run. Returns 404 until the task reaches succeeded.
POST /api/v1/tasks/{task_id}/cancel Cancel a queued task. Returns 409 if not in queued state.
DELETE /api/v1/tasks/{task_id} Delete the task and its blobs. Returns 409 if INPROGRESS and the 2-minute grace window has not elapsed. 204 on success.

POST /api/v1/tasks/search searches your own tasks with filters and pagination. All body fields are optional; an omitted filter is unconstrained, while an empty list matches nothing.

Field Type Description
user_id list[str] Owner API keys to match. Ignored for ordinary keys — your search is always scoped to your own tasks.
device_name list[str] Match these device names.
device_class list[LUCIDAC | REDAC | SIMULATOR] Match run tasks via the device's class and compile tasks via their backend.
type list[compile | run] Match these task kinds.
state list[TaskStateEnum] Match against each task's latest state.
from datetime (ISO 8601) Start of the creation-time window.
to datetime (ISO 8601) End of the creation-time window.
limit int (1–1000) Page size. Default 50.
offset int (≥0) Number of leading matches to skip. Default 0.

Filtering combines values with OR within a field and AND across fields. The window defaults to the last 24 hours when from/to are omitted and may span at most 90 days; a wider window is rejected with 422. Unknown body fields are also rejected with 422 (the schema is extra=forbid).

The response is a paginated envelope, TaskSearchResponse:

class TaskSearchResponse(BaseModel):
    items: list[TaskSearchItem]  # task summary + user_id
    total: int                   # full count of matching tasks, ignoring limit/offset
    limit: int
    offset: int
    next_offset: int | None      # offset + limit if more remain, else null

Non-versioned endpoints

Method Path Auth Description
GET /health none Liveness probe, returns {"status": "healthy"} when the server is operational.

Common types and workflows

All task creation endpoints return the same shape:

class TaskCreatedResponse(BaseModel):
    id: UUID
    type: "compile" | "run"
    state: TaskStateEnum  # always "queued" at creation
    created_at: datetime

Task state values are queued, inprogress, succeeded, failed, and cancelled; the last three are terminal. Errors use a consistent body of {"detail": "<message>"}.

Status Meaning
400 Bad request (e.g. backend = SIMULATOR on a compile task).
403 Auth failure (missing, disabled, or unknown key) or device access denied.
404 Task / device not found, or task result not yet available.
409 State conflict (cancel a non-queued task, delete an in-flight task within grace).
422 Validation failure (e.g. a /tasks/search window wider than 90 days, or an unknown filter field).
429 Rate limit exceeded for the device class.
500 Server error.
503 Target device not available.

Analog Cloud is a distributed system made up of a server (accepting and processing HTTP requests), a database (holding task data), a queue per registered device (a list of pending jobs to be processed), and workers that perform the actual processing of tasks. Different components may be deployed to different physical machines, but this is transparent from an API-only perspective. It is, however, useful to understand how tasks are processed in order to understand why a job might take a long time or fail:

sequenceDiagram autonumber actor User participant API as REST API participant Q as Queue / Worker participant DB as Storage User->>API: POST /api/v1/tasks/{compile|run} API->>DB: persist task, blobs API->>Q: enqueue API-->>User: 201 TaskCreatedResponse (state=queued) loop until terminal User->>API: GET /api/v1/tasks/{id}/status API-->>User: TaskStatusResponse end Q->>DB: write result + log (state -> succeeded/failed) User->>API: GET /api/v1/tasks/{id}/result API-->>User: APB bytes (compile) or JSON measurements (run) User->>API: GET /api/v1/tasks/{id}/log API-->>User: log lines opt cleanup User->>API: DELETE /api/v1/tasks/{id} API->>DB: drop task and blobs API-->>User: 204 end

For Developers: Generating clients

The OpenAPI document served at https://redac.anabrid.com/api/docs / https://redac.anabrid.com/api/redoc (with raw JSON at https://redac.anabrid.com/openapi.json, assuming anabrid's production setup) is suitable as input to any standard OpenAPI client generator. analogcli is the reference Python client; equivalent clients in other languages can be produced from the same schema.