API Reference#
Everything the console and astra do goes through one HTTP API, in JSON.
This page explains how to build a request — the base URL, how to
authenticate, errors, lists and limits — and makes a first call. The
reference pages list every operation, with its parameters, bodies, responses
and examples in curl, Python and JavaScript.
| Reference | What it covers |
|---|---|
| Astraeus | Runs, workers, machines and GPUs, metrics and usage, schedules, endpoints, replica groups, drives, data sources, credentials, a workspace's events and run templates |
| Eos | Models, deployments, API keys, shares, the model library, the Playground's routes |
| Eos OpenAI-compatible API | /v1/models, /v1/chat/completions, /v1/completions, /v1/embeddings on Eos gateways |
| Anemoi | Agents, their runs and receipts, approvals, guardrails, budgets, flows, evaluations, evidence packs, the marketplace |
| Hesperus | Notebooks and their runtimes |
| Accounts and administration | Sign-in, API tokens, organisations, members, single sign-on, audit, usage, alerts, event streams, clusters, machines, reservations, workspaces |
The reference shows each request as curl, Python and JavaScript; it does not send requests from the page.
Base URLs#
| Scope | Base URL |
|---|---|
| The console API: you, organisations, workspaces, clusters | https://console.astralyx.cloud/api/v1 |
| A workspace on a cluster: its runs, machines, data, models, agents, notebooks | https://console.astralyx.cloud/api/v1/orgs/{org}/workspaces/{workspace}/clusters/{cluster}/api |
| Eos gateways: calling deployments, OpenAI-style | https://console.astralyx.cloud/inference/v1 (hosted gateway), or a gateway on your machines; see Eos OpenAI-compatible API |
Build a workspace's endpoint#
Work in a workspace happens on a cluster, so its base URL names three things, all short names:
| Part | Where to find it | Example |
|---|---|---|
{org} |
The console's address: console.astralyx.cloud/o/{org}/…, or GET /api/v1/me (orgs[].slug) |
acme |
{workspace} |
The console's address: /o/{org}/w/{workspace}/…, or GET /api/v1/orgs/{org}/workspaces |
vision |
{cluster} |
The workspace's Settings, or GET /api/v1/orgs/{org}/workspaces/{workspace}/clusters. On Astraeus Cloud it is usually default. |
default |
$ export ASTRA_URL=https://console.astralyx.cloud
$ export ASTRA_TOKEN=ast_pat_…
$ export WS="$ASTRA_URL/api/v1/orgs/acme/workspaces/vision/clusters/default/api"
The workspace must have access to the cluster (404 NOT_BOUND otherwise).
Every path of the Astraeus, Eos, Anemoi and Hesperus references that is not
marked as a console path goes after $WS: GET $WS/jobs lists the
workspace's runs on that cluster.
Authentication#
Send a token in the Authorization header:
| Credential | Acts as | Made by | Use it for |
|---|---|---|---|
Personal API token, ast_pat_… |
You, with your roles everywhere | Account & tokens in the console, or POST /api/v1/me/tokens |
Scripts, CI |
CLI session, ast_sess_… |
You | astra login |
astra |
| Eos API key | A workspace's deployments | The workspace's API keys | The OpenAI-compatible API only |
A token acts as the person who created it, with their role in each
organisation and workspace. See API tokens and automation.
No credentials, or an unknown, revoked or expired token, answer
401 UNAUTHENTICATED; a role that does not allow the operation answers
403. Each operation's description names the role it needs; see
Roles and permissions.
A first call#
Check who you are:
$ curl -sS "$ASTRA_URL/api/v1/me" -H "Authorization: Bearer $ASTRA_TOKEN"
{"id":"0192…","email":"[email protected]","name":"Ada","operator":null,
"orgs":[{"id":"0192…","slug":"acme","name":"Acme Research","role":"admin"}]}
Submit a run in a workspace, then read its workers and logs:
$ curl -sS -X POST "$WS/jobs" -H "Authorization: Bearer $ASTRA_TOKEN" -H "Content-Type: application/json" \
-d '{"metadata": {"name": "hello"},
"spec": {"task_template": {"image": "busybox", "command": "echo", "args": ["hi"],
"requested_resources": {"cpu_cores": 1, "memory_bytes": 1073741824}}}}'
$ curl -sS "$WS/tasks?job=hello" -H "Authorization: Bearer $ASTRA_TOKEN"
$ curl -sS "$WS/tasks/hello-0/logs?tail=100" -H "Authorization: Bearer $ASTRA_TOKEN"
{"logs":"hi\n"}
Names and the workspace#
- Names are the workspace's own. You write and read
train, in paths, in query parameters (job,name,task), in metric matchers (match=task:train-0) and in bodies. A name containing.is refused (400 INVALID_NAME). - Everything stays in the workspace. A reference in a body must name an
object of the same workspace (
403 NAMESPACE_FORBIDDEN); listings show only the workspace's objects. - Machines are those of the workspace's pools. Others answer
404 NODE_NOT_FOUND.
Resources and path aliases#
Resources have the shape {"metadata": {"name", "labels"}, "spec": {…},
"status": {…}}. You create one with metadata and spec; Astralyx owns
status. The reference uses the API's collection names; the product's names
are accepted as aliases, and responses use the API's field names:
| Product name | API path | Alias |
|---|---|---|
| Runs | /jobs |
/runs |
| Workers | /tasks |
/workers |
| Machines | /nodes |
/machines |
| Drives | /datavolumes |
/drives |
| Mounts | /datavolume-claims |
/mounts |
| Data sources | /connectors |
/data-sources |
| Credentials | /external-secrets |
/credentials |
| Schedules | /cronjobs |
/schedules |
| Replica groups | /scaling-groups |
/replica-groups |
The alias works in the first path segment, in the second after metrics/
(/metrics/workers/{name}) and in the third after nodes/{name}/
(/machines/{name}/workers).
Lists and pagination#
- A workspace's collections answer
{"items": [ … ]}with every matching object: they are not paginated. Most takestate,labelSelector(key=value,key2=value2) andorder(asc,desc). - Logs of what happened — a workspace's events, a cluster's events, an
organisation's audit log — are newest first and paged with
limit(default 100) andbefore: pass the lastidof a page to get the next. Events also answernext_before, the value to pass. - Watches.
GETon a watchable collection with?watch=trueanswers a stream of server-sent events instead of a list: every current object asADDED, thenMODIFIEDandDELETEDas they happen, a comment every 15 s to keep the connection open, andERRORif your client falls behind (list again, then watch again).
$ curl -sSN "$WS/jobs?watch=true" -H "Authorization: Bearer $ASTRA_TOKEN"
data: {"type":"ADDED","name":"train","object":{…},"revision":88190}
data: {"type":"MODIFIED","name":"train","object":{…},"revision":88213}
Errors#
A refused or failed request answers an HTTP status and a JSON body with a stable code:
Match on code; message is for people and may change; detail is
omitted when empty. Server faults are redacted (500 INTERNAL_SERVER_ERROR,
502 BAD_GATEWAY, 504 TIMEOUT, no detail): retry them with backoff, as
503. Every code is listed in Errors; the
OpenAI-compatible API answers OpenAI's error shape instead.
Limits#
| Limit | Value |
|---|---|
| Request body, a workspace on a cluster | 16 MiB (400 BODY_TOO_LARGE) |
| JSON response, a workspace on a cluster | 256 MiB (503 RESPONSE_TOO_LARGE: narrow the request) |
| Sign-up | 20 per hour per client address |
| Sign-in with a password | 10 per 15 minutes per address and e-mail; 100 per address; 50 per e-mail |
| Forgotten password | 10 per hour per address |
| CLI sign-in (device flow) | 30 per hour per address |
| Hosted Eos gateway, unknown API keys | 30 per minute per address |
The MCP server (/mcp) |
30 requests at once, then 30 per minute, per token |
Beyond a sign-in limit the API answers 429 TOO_MANY_ATTEMPTS. Other
requests have no rate limit; a cluster at capacity answers
503 OVERLOADED with Retry-After: 1: retry after that many seconds. See
Limits.
Retries and idempotency#
There is no idempotency key. Most objects are created under the name you
give, so a create that you retry after a lost answer is refused with
409 …_ALREADY_EXISTS if the first one succeeded: read the object to
confirm it is yours.
Versioning#
The version is in the path: /api/v1. Responses can gain fields: ignore
fields you do not know. Run specifications are strict the other way: a field
the API does not know is refused (400 UNKNOWN_FIELD), so a typo does not
pass silently.