Runs and results
Each fire (cron, manual, or API) makes a run with a receipt that you can poll.
Polls always work. On api.dev.sume.com and api.sume.com,
run webhooks deliver the same receipt without a loop.
Run lifecycle
| Status | Meaning |
|---|---|
queued | Accepted, not started. |
processing | The Agent works on the run. |
completed | Finished. output and artifacts are populated. |
failed | Finished with an error. |
canceled | A cancel request stopped it. |
skipped | Never ran, because another run was active. |
The Action vocabulary spells it canceled with one l. The Action statuses map
the internal statuses to new names: done shows as completed, error as
failed, and cancelled as canceled. Do not assume that job-side status
strings transfer.
The run receipt
GET /v1/action-runs/{run_id} returns the full receipt.
| Field | Notes |
|---|---|
id, object | object is action.run. |
action | { "id", "title", "trigger_type" }. |
status | See the table above. |
trigger | { "source": "cron" | "manual" | "api", "idempotency_key" }. |
created_at, started_at, finished_at | started_at and finished_at are null until they occur. |
output_schema | { "name", "strict", "source" }, where source is default, action_default, or request_override. |
output | Structured result. null unless status is completed or failed. |
output_error | { "code", "message", "details" } when projection failed. null unless status is completed or failed. Refer to When output cannot be produced. |
primary_output_key | null unless status is completed. |
primary_output_url | Resolved URL for primary_output_key. null unless status is completed. |
artifacts | Media harvested from the run. Empty until the run is terminal. |
usage | { "currency": "USD", "billable_amount_usd_micros", "generation_spend_cap_usd_micros" }, or null when Sume could not read the spend. |
error | { "code", "message" }. code is output_error.code when one is set. If not, it is action_run_failed. Non-null only when status is failed. |
skip_reason | previous_run_active on a skipped run, otherwise null. |
request_id | Log this. |
status_url, result_url, cancel_url | Use these URLs. Do not build URLs yourself. |
events_url | Always null. The API does not expose run lifecycle events. |
cancelable | true while queued or processing. |
next_action | Recommended next step. Refer to the section below. |
idempotency_hit | true when this receipt is an idempotency replay. |
usage.billable_amount_usd_micros is the generation spend of this run. It
is the same total that Sume uses to enforce the
generation_spend_cap_usd_micros of the run. This total includes both reserved
and captured amounts. It increases while the run is in flight, and it settles
when the run terminates.
Know two limits of this value. First, it does not include the LLM turn of the
agent. That turn bills the separate Agent wallet. Thus, the value is not the
total cost of the run. Second, it is a receipt figure, not an invoice.
GET /v1/usage is still the authoritative billing record.
usage is null when Sume could not read the spend at all. That is different
from 0, which means that the run truly spent nothing yet.
Poll for completion
GET /v1/action-runs/{run_id}/status returns a trimmed payload for poll
loops:
Branch on next_action:
next_action | When | Do |
|---|---|---|
poll_status | queued or processing | Continue to poll with backoff. |
retry_later | skipped | Another run was active. Try again. |
none | Every terminal run — completed, failed, canceled | There is nothing more to fetch. On a failure, read error and output_error on this receipt. |
These three values are the full set. events_url is always null, because
there is no public run events route. Thus, no receipt tells you to inspect one.
Fetch the result
GET /v1/action-runs/{run_id}/result returns the full receipt, but only after
the run is terminal. While the run is queued or processing, it returns
409 run_not_completed, with the current status in details.status.
Structured output
Schedule runs use the same structured-output contract as Format runs.
Structured output documents this contract one
time. These items all apply here with no change: the supported schema subset,
SumeMediaFile, the built-in sume/action-run-output/v1 schema, the URL gate,
primary_output_key resolution, and the output_error failure modes.
Two items are specific to Scheduled:
- A schedule binds its default schema in the dashboard, not at author time. The
receipt shows this default as
output_schema.source: "action_default". - A per-request
output_schemaonPOST /v1/actions/{action_id}/runsoverrides it for that run. The receipt shows it asrequest_override.
List runs
limit accepts 1–100, and the default is 50. The response is a page:
{ "data": [ ... ], "has_more": false, "next_cursor": null }. To read the full
history, send next_cursor back as cursor until has_more is false. The
cursor is opaque. If Sume did not create the cursor, the API rejects it with
400 invalid_request.
GET /v1/actions pages the same way: send next_cursor back as cursor until
has_more is false.
You can also read a single run under its Action at
GET /v1/actions/{action_id}/runs/{run_id}.
Cancel a run
Cancel requires actions:write and is idempotent. If you cancel a run that is
already terminal, the API returns that terminal receipt with 200.
End-to-end example
In production, use exponential backoff, not a fixed five-second sleep.