Queues
Hand off background work to a queue and let a function consume it — decouple slow work from the request path, retry failures automatically, and dedupe with idempotency keys.
Queues let you push work out of the request path. Enqueue a job, return to your caller immediately, and a bound function processes the job in the background — with automatic retries and a dead-letter path when a job exhausts them. Use queues for anything that's slow or flaky: calling a third-party API, generating a file, fanning out notifications.
A queue is just a name. You bind one consumer function to it, then send
jobs to it. Sends come from a function via ctx.queue.send or from the
admin API; the binding is managed with amba functions consume.
Bind a consumer
A queue does nothing until a function is bound to consume it. Bind with the CLI:
This makes process-order the consumer for the orders queue. Queue
names match ^[a-z][a-z0-9_-]*$ (≤58 chars). Pass --paused to create the
binding paused — jobs dead-letter until you resume it.
| Method | Path | Description |
|---|---|---|
| PUT | /admin/projects/:projectId/queue/bindings | Upsert a binding. Body { queue_name, function_name, status? }. |
| GET | /admin/projects/:projectId/queue/bindings | List bindings. |
| DELETE | /admin/projects/:projectId/queue/bindings/:queue?confirm=:queue | Remove a binding. |
| POST | /admin/projects/:projectId/queue/send | Enqueue a job. |
The CLI also exposes amba functions consumers list and
amba functions consumers unbind <queue>. A binding's status is active
or paused; rebinding the same queue overwrites the consumer and resets
status to active.
Send a job
From inside a function, the runtime gives you ctx.queue.send:
Or send via the admin API directly:
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Queue name. Must already have a bound consumer. |
payload | any | no | The job body, delivered verbatim to the consumer. |
delay_seconds | number | no | Non-negative. Delays delivery by this many seconds. |
idempotency_key | string | no | ≤256 chars. A repeat within 24h returns the original job. |
Sending to a queue with no bound consumer returns 400 UNKNOWN_QUEUE —
bind one first. When you pass an idempotency_key, a duplicate send within
24 hours is collapsed: the response returns the original job_id with
deduplicated: true and the job is not re-enqueued.
Consume a job
A bound consumer receives each job as an HTTP POST to its handler. The
JSON body carries the queue name, your payload, and the enqueue time:
The originating queue name is also available in the x-amba-queue request
header.
Acknowledgement and retries
The consumer's HTTP status controls delivery:
- 2xx — the job is acknowledged and removed.
- 5xx, 408, or 429 — transient failure; the job is retried with backoff.
- Other 4xx — the consumer rejected the payload's shape; the job is not retried and goes straight to the dead-letter path.
A job that exhausts its retries is dead-lettered rather than dropped. Paused bindings dead-letter immediately while paused — you can keep enqueuing while a consumer is drained.
From an agent
There are no dedicated queue MCP tools — queues are wired up through the
function surface. An agent binds a consumer by deploying the function and
calling the binding endpoint, and enqueues either from within a function
(ctx.queue.send) or via POST /queue/send. See Functions
for deploying the consumer.