Background runs let you submit an agent task and receive an immediate acknowledgement, then poll for the result at your own pace. This is the right choice for long-running analyses, batch processing, and workflow steps where you cannot hold an HTTP connection open for the full duration of execution.
All requests require a valid bearer token in the Authorization header.
Submit a background run
POST /api/agents/{agentId}/runs/background
Queues the agent run for asynchronous execution and returns immediately with a runId and status: "QUEUED". The request accepts the same body as the synchronous run endpoint.
Path parameters
The unique identifier of the agent to run.
Request body
The user’s input or query for the agent.
UUID of an existing session to continue. Omit to start a new session — the server generates one automatically.
Associates the run with a specific user for memory scoping and audit trails.
Tenant identifier for multi-tenant deployments.
When true, the agent generates suggested follow-up questions appended to the output.
Array of multimodal inputs. Each entry contains type (MIME type) and data (base64 or URL).
Optional model overrides (model, temperature, maxTokens).
Response
Unique identifier for the queued run. Use this to poll for status.
Always "QUEUED" on successful submission.
curl --request POST \
--url "http://localhost:8080/api/agents/finance_agent/runs/background" \
--header "Authorization: Bearer {token}" \
--header "Content-Type: application/json" \
--data '{
"message": "Analyze Q3 2025 earnings for the top 10 S&P 500 constituents.",
"userId": "user_abc123",
"sessionId": "550e8400-e29b-41d4-a716-446655440000"
}'
Example response
{
"runId": "run_7f3a9c12-4e2b-4d1a-8c5f-abc123def456",
"status": "QUEUED"
}
Poll for run status
GET /api/agents/{agentId}/runs/{runId}/status
Returns the current state of a background run as an AgentRun entity. Poll this endpoint until status reaches a terminal state (COMPLETED, FAILED, or CANCELLED).
The agent that owns the run.
The run identifier returned when the background run was submitted.
Run status values
| Status | Description |
|---|
QUEUED | The run has been accepted and is waiting in the job queue. |
RUNNING | The agent is actively processing the request. |
COMPLETED | Execution finished successfully. Check output for the response. |
FAILED | An unrecoverable error occurred. |
PAUSED | The agent triggered a Human-in-the-Loop gate. Call /runs/{runId}/continue to approve or reject. |
CANCELLED | The run was cancelled via DELETE /api/agents/{agentId}/runs/{runId}. |
The agent that executed this run.
The session this run belongs to.
Current execution status.
ISO-8601 timestamp when the run was queued.
ISO-8601 timestamp when the run reached a terminal status. null while still running.
The agent’s response content, available when status is "COMPLETED".
curl --request GET \
--url "http://localhost:8080/api/agents/finance_agent/runs/run_7f3a9c12/status" \
--header "Authorization: Bearer {token}"
Example response (completed)
{
"id": "run_7f3a9c12-4e2b-4d1a-8c5f-abc123def456",
"agentId": "finance_agent",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"createdAt": "2026-05-06T10:00:00Z",
"completedAt": "2026-05-06T10:00:47Z",
"output": "## Q3 2025 Earnings Summary\n\nApple (AAPL): Revenue $94.9B, EPS $1.64..."
}
Batch status polling
GET /api/agents/{agentId}/runs/status?runIds=id1,id2,id3
Check the status of up to 100 background runs in a single HTTP request. Run IDs that have no corresponding record are silently omitted from the response.
The agent that owns the runs.
Comma-separated list of run IDs to check. Maximum 100 IDs per request.
curl --request GET \
--url "http://localhost:8080/api/agents/finance_agent/runs/status?runIds=run_7f3a9c12,run_8a4b2d34,run_9c5e3f56" \
--header "Authorization: Bearer {token}"
Example response
[
{
"id": "run_7f3a9c12-4e2b-4d1a-8c5f-abc123def456",
"status": "COMPLETED",
"createdAt": "2026-05-06T10:00:00Z",
"completedAt": "2026-05-06T10:00:47Z"
},
{
"id": "run_8a4b2d34-1c3e-4f2a-9d6b-bcd234ef5678",
"status": "RUNNING",
"createdAt": "2026-05-06T10:01:00Z",
"completedAt": null
}
]
Polling loop example
The following TypeScript example submits a background run and polls for completion with exponential backoff:
interface AgentRun {
id: string;
status: string;
output?: string;
completedAt?: string;
}
async function runInBackground(
agentId: string,
message: string,
token: string
): Promise<AgentRun> {
const baseUrl = "http://localhost:8080";
// Submit the background run
const submitRes = await fetch(
`${baseUrl}/api/agents/${agentId}/runs/background`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ message }),
}
);
const { runId } = await submitRes.json();
console.log(`Run queued: ${runId}`);
// Poll until terminal state
const TERMINAL = new Set(["COMPLETED", "FAILED", "CANCELLED"]);
let delayMs = 1000;
while (true) {
await new Promise((r) => setTimeout(r, delayMs));
const statusRes = await fetch(
`${baseUrl}/api/agents/${agentId}/runs/${runId}/status`,
{ headers: { Authorization: `Bearer ${token}` } }
);
const run: AgentRun = await statusRes.json();
console.log(`Status: ${run.status}`);
if (TERMINAL.has(run.status)) {
if (run.status === "COMPLETED") {
console.log("Output:", run.output);
} else {
console.error("Run did not complete:", run.status);
}
return run;
}
// Exponential backoff, capped at 10 seconds
delayMs = Math.min(delayMs * 1.5, 10_000);
}
}
runInBackground(
"finance_agent",
"Analyze Q3 2025 earnings for the top 10 S&P 500 constituents.",
"your-token-here"
);
For batch workloads, use the batch status endpoint (?runIds=...) instead of individual polling calls. Checking 10 runs at once with one request every 3 seconds uses ~20 requests/minute compared to ~200 for individual polls.