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

StatusMeaning
queuedAccepted, not started.
processingThe Agent works on the run.
completedFinished. output and artifacts are populated.
failedFinished with an error.
canceledA cancel request stopped it.
skippedNever 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.

FieldNotes
id, objectobject is action.run.
action{ "id", "title", "trigger_type" }.
statusSee the table above.
trigger{ "source": "cron" | "manual" | "api", "idempotency_key" }.
created_at, started_at, finished_atstarted_at and finished_at are null until they occur.
output_schema{ "name", "strict", "source" }, where source is default, action_default, or request_override.
outputStructured 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_keynull unless status is completed.
primary_output_urlResolved URL for primary_output_key. null unless status is completed.
artifactsMedia 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_reasonprevious_run_active on a skipped run, otherwise null.
request_idLog this.
status_url, result_url, cancel_urlUse these URLs. Do not build URLs yourself.
events_urlAlways null. The API does not expose run lifecycle events.
cancelabletrue while queued or processing.
next_actionRecommended next step. Refer to the section below.
idempotency_hittrue 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_actionWhenDo
poll_statusqueued or processingContinue to poll with backoff.
retry_laterskippedAnother run was active. Try again.
noneEvery terminal run — completed, failed, canceledThere 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_schema on POST /v1/actions/{action_id}/runs overrides it for that run. The receipt shows it as request_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.

Next