API reference
Call Armada's REST and gRPC APIs directly: base address, a worked example, and the main endpoints.
Armada has two APIs: gRPC, which armadactl and the client libraries use, and REST (HTTP with JSON), for most of the same operations from scripts or languages without a gRPC client. This page shows you how to call the REST API, and where to find the definitions for both.
Before you start
You need an Armada installation: a laptop install (Getting started), or a team installation (an Armada that your platform team runs for many users). You also need its API addresses:
| API | Laptop install | Team installation |
|---|---|---|
| REST | http://localhost:30001 | Ask your platform team |
| gRPC | localhost:30002 | The armadaUrl in your ~/.armadactl.yaml |
Call the REST API
Every REST path starts with /v1, unless your platform team has added a prefix. (Lookout's own API, at localhost:30000/api/v1, is a different API used by the web UI.)
Step 1. Create a queue
curl -X POST http://localhost:30001/v1/queue \
-H 'Content-Type: application/json' \
-d '{"name": "api-demo", "priorityFactor": 1}'Check it:
curl http://localhost:30001/v1/queue/api-demoSuccess: creating returns {}, and the check returns the queue as JSON, starting {"name":"api-demo","priorityFactor":1,....
Wait about 10 seconds before the next step: Armada checks for new queues every 10 seconds.
Step 2. Submit a job
curl -X POST http://localhost:30001/v1/job/submit \
-H 'Content-Type: application/json' \
-d '{
"queue": "api-demo",
"jobSetId": "rest-1",
"jobRequestItems": [{
"namespace": "default",
"podSpec": {
"restartPolicy": "Never",
"containers": [{
"name": "hello",
"image": "alpine:3.21",
"command": ["sh", "-c", "echo hello from REST"],
"resources": {
"requests": {"cpu": "100m", "memory": "64Mi"},
"limits": {"cpu": "100m", "memory": "64Mi"}
}
}]
}
}]
}'Success: it returns the new job's ID:
{"jobResponseItems":[{"jobId":"<job-id>"}]}The job follows the same rules as any Armada job: by default, each container's limits must equal its requests, but your platform team can allow higher limits (the server's submission.maxOversubscriptionByResourceRequest). See Submitting jobs.
Step 3. Check the job's state
curl -X POST http://localhost:30001/v1/job/status \
-H 'Content-Type: application/json' \
-d '{"jobIds": ["<job-id>"]}'Success: after about 30 seconds:
{"jobStates":{"<job-id>":3}}Run it a few times to see the job move along. In testing it went 5 (straight after submitting, before Armada had recorded it), then 0, 7, 2 and 3.
States are returned as numbers. 3 means the job succeeded:
| Number | State | Number | State |
|---|---|---|---|
0 | QUEUED | 6 | SUBMITTED |
1 | PENDING | 7 | LEASED |
2 | RUNNING | 8 | PREEMPTED |
3 | SUCCEEDED | 9 | CANCELLED |
4 | FAILED | 10 | REJECTED |
5 | UNKNOWN |
Step 4. Clean up
curl -X DELETE http://localhost:30001/v1/queue/api-demoSuccess: it returns {}.
Logging in
A laptop install has no login. On a team installation, send your login in the Authorization header with every request, the same way the gRPC API receives it:
# A token from your login provider
curl -H "Authorization: Bearer <token>" https://<your-armada-rest-address>/v1/queue/<queue>
# Or a username and password, if your installation uses them
curl -u <user>:<password> https://<your-armada-rest-address>/v1/queue/<queue>Without credentials you get HTTP 401 (Request could not be authenticated ...); without the right permission, HTTP 403 with the same message armadactl shows. /health needs no login.
REST endpoints
| Method and path | What it does |
|---|---|
POST /v1/job/submit | Submit jobs |
POST /v1/job/status | Get jobs' current states |
POST /v1/job/details, POST /v1/job/errors | Get jobs' details, or their error messages |
POST /v1/run/details | Get details of jobs' runs |
POST /v1/job/cancel, POST /v1/jobset/cancel | Cancel jobs, or a whole job set |
POST /v1/job/reprioritize | Change the priority of jobs that haven't finished, including running jobs |
POST /v1/job/preempt | Preempt jobs |
POST /v1/job-set/{queue}/{id} | Stream a job set's events. The body can be {}; the response is one JSON object per line, each {"result": {...}}. |
POST /v1/queue, GET /v1/queue/{name}, PUT /v1/queue/{name}, DELETE /v1/queue/{name} | Create, read, replace or delete a queue. POST on an existing name also replaces that queue |
GET /v1/batched/queues | List queues, one JSON object per line. (There's no GET /v1/queues.) |
POST /v1/queues/active | List queues with active jobs |
POST /v1/batched/create_queues, PUT /v1/batched/update_queues | Create or replace several queues at once |
POST /v1/job/statusUsingExternalJobUri | Get a job's state by the external URI a tool such as Airflow gave it |
POST /v1/retry-policy, GET /v1/retry-policies, GET, PUT or DELETE /v1/retry-policy/{name} | Manage retry policies |
GET /v1/job/{job_id}/scheduler-report, GET /v1/queue/{queue_name}/scheduler-report, GET /v1/scheduling-report | Get the scheduler's latest report for a job, a queue, or the whole scheduler (the same reports as armadactl get job-report, queue-report and scheduling-report) |
Request and response fields are described in the OpenAPI specification, which your installation also serves at <rest-address>/swagger.json. It lists the /v1/node/... paths, which REST doesn't serve, and leaves out the scheduler report paths, which are in pkg/api/schedulerobjects/api.swagger.json.
Cancelling or preempting all the jobs on one node or executor is only in the gRPC API (the Node and Executor services, or armadactl cancel and armadactl preempt with node or executor). The /v1/node/... and /v1/executor... paths in the API definitions return HTTP 404, because the REST API doesn't serve them.
The gRPC API
The gRPC API is defined in Protocol Buffers files in pkg/api. The services you're most likely to use:
| Service | What it covers |
|---|---|
Submit | Submitting, cancelling, reprioritizing and preempting jobs |
QueueService | Creating, reading, updating and deleting queues. gRPC only: cordoning them, cancelling a queue's jobs by state, preempting its leased, pending and running jobs |
Event | Streaming job set events |
Jobs | Looking up jobs' status, details and errors |
RetryPolicyService | Managing retry policies |
Node | Cancelling or preempting the jobs on one node (needs cancel_any_jobs or preempt_any_jobs) |
SchedulerReporting | The scheduler's job, queue and scheduling reports (defined in pkg/api/schedulerobjects) |
You can generate a client for any language that supports gRPC from these files. For Python, Go, Java, Scala, .NET and Rust, use the ready-made client libraries instead.
Troubleshooting
| What you see | Cause | Fix |
|---|---|---|
Not Found (HTTP 404) | The path doesn't start with /v1, uses /api/v1, or doesn't exist (for example GET /v1/queues) | Use http://<host>:<port>/v1/... and a path from the table. |
HTTP 401, Request could not be authenticated ... | No login, or a wrong one | Add the Authorization header (see Logging in). |
HTTP 403, ... lacks permission <right> ... | You're logged in, but don't have the right | Ask your platform team. On a laptop install, the anonymous user lacks create_retry_policy, preempt_any_jobs and cordon_queue, so those calls get this error. |
State 5 (UNKNOWN) straight after submitting | Armada hasn't recorded the job yet | Ask again after a few seconds. If it stays 5, check the job ID: Armada returns 5 for any ID it doesn't know. |
Connection refused | Wrong address or port, or Armada isn't running | A laptop install's REST API is on port 30001. gRPC is on 30002. |
Submission errors such as namespace is a required field | The job breaks a submission rule | Check the job: it needs a namespace, exactly one pod, and resources with requests and limits for the same resources. By default limits must equal requests; your platform team can allow higher limits (the server's submission.maxOversubscriptionByResourceRequest). The error names the rule it broke. |
| States are numbers, not names | REST returns states as numbers | See the table in Step 3. |
Last updated on