Runtime-facing endpoint used by an executing task to report progress, intermediate output, completion, failure, or to pause for human input. This is the only signal the platform uses to mark a platform-managed run as completed or failed.
Endpoint
POST /api/runs/{runId}/callback
Auth: Authorization: Bearer <agent_api_key>
The runId comes from payload.runId in the task payload that the platform sends to your runtime at trigger time. The agent_api_key is delivered to the runtime as an environment variable on the runtime environment — it is not in the per-run payload.
Payload variants
The body is a discriminated union on type.
started
Marks the run as running.
{ "type": "started" }
output
Reports intermediate or terminal output.
{
"type": "output",
"output": { "step": 1, "pages_scanned": 12 }
}
To mark the run complete, add complete: true:
{
"type": "output",
"output": { "summary": "done" },
"outputs": 42,
"complete": true
}
To mark the run failed, add failed: true and an error:
{
"type": "output",
"failed": true,
"error": {
"name": "TimeoutError",
"message": "upstream did not respond within 30s"
}
}
| Field | Type | Description |
|---|---|---|
output | object | Domain payload (rendered in the platform UI). |
complete | boolean | Set true on success; transitions status → completed. |
failed | boolean | Set true on failure; transitions status → failed. |
error | object | { name?, message?, stack? } — required when failed=true. |
outputs | integer | Count of agent-defined output units; latest non-null value wins. |
waiting
Pause the run for human-in-the-loop input. Supported only by runtimes that implement waitpoints — check the agent's runtime descriptor.
{
"type": "waiting",
"tokenId": "wait_abc123",
"description": "Approve the generated summary",
"output": { "draft": "…" }
}
| Field | Type | Description |
|---|---|---|
tokenId | string | Waitpoint token id used by the runtime to resume execution. |
description | string | Shown to the human reviewer. |
output | object | Optional context displayed alongside the form. |
Response
200 OK with an empty body on success.
Errors
| Status | Reason |
|---|---|
401 | Missing or invalid agent_api_key. |
404 | runId does not exist or does not belong to this agent. |
409 | Backward state transition (e.g. callback after the run was cancelled). |
422 | Payload failed validation. |
429 | Per-agent rate limit. |
SDK
import { createAgentClient } from '@cxpa/sdk/agent'
const cxpa = createAgentClient({
baseUrl: process.env.CXPA_API_URL!,
apiKey: triggerPayload.agentApiKey,
runId: triggerPayload.runId,
credentialsToken: triggerPayload.credentialsToken,
})
await cxpa.started()
await cxpa.output({ output: { step: 1 } })
await cxpa.complete({ output: { summary: 'done' }, outputs: 42 })