Sume schedule run statuses: completed, failed, canceled, skipped
Sume schedule runs report completed, failed, canceled with one l, and skipped. They are a remap of internal statuses, so job-side strings do not carry over.

A Sume schedule run moves through queued, processing, then ends as completed, failed, canceled or skipped. These strings are a remapping of internal ones: done surfaces as completed, error as failed, and cancelled as canceled with one l. A switch statement copied from job handling will miss some of them.
From Runs and results and Run a schedule via API, read on 2026-10-03.
What each status means
Only completed guarantees that output and artifacts are populated. The other terminal states carry no result, and skipped is the one that surprises people because nothing actually went wrong.
| Status | Meaning | Has output? |
|---|---|---|
| queued | Accepted, not started | No |
| processing | The agent is working | No |
| completed | Finished | Yes |
| failed | Finished with an error | No |
| canceled | Stopped by a cancel request | No |
| skipped | Never ran, because another run was active | No |
Skipped is a successful HTTP call
When an overlapping trigger arrives under the default on_active_run: skip, the API answers 200 with a receipt whose status is skipped and whose skip_reason is previous_run_active. A run row is recorded. Under reject, the same situation is a 409 action_run_in_progress and no run row exists.
An idempotency replay also returns 200 instead of 202: it hands back the original receipt with idempotency_hit: true. So HTTP status cannot tell you whether work started. Branch on the receipt's status, not on 200 versus 202.
A handler that will not drop a state
List every terminal status explicitly, and make the default branch raise or alert instead of silently passing. Treat skipped as expected if overlap is by design, and as a signal to lengthen the cadence if it is not.
Cancel is idempotent. Canceling a run that is already terminal returns that terminal receipt with 200, and it needs actions:write, so a read-only monitor cannot cancel by accident.
Webhooks only cover some of these
Run webhooks send one terminal event per run family, and for schedules that is action.run.terminal. A failed run arrives with status: "ERROR" and a populated error, with the full receipt as payload. Canceled and skipped runs deliver no webhook at all, so a consumer that waits for a POST on those will wait forever.
For canceled runs, trust the cancel response and poll status_url until payload.status is canceled. For skipped runs, read status on the response you already received. The create call told you.
Testing the mapping
Write one unit test that feeds each of the six status strings into your handler and asserts a distinct outcome for each. Include the misspelling cancelled as a negative case: if your code accepts it, it was probably copied from another system, and the API will never send it.
Also test the 200 path. A receipt with idempotency_hit: true and a receipt with status skipped both arrive with HTTP 200, and your code should handle them differently: the first is a safe replay of an earlier run, the second is a run that never started.
Sources
Related posts
More in Developers
- Paging Sume schedule runs: limit 1-100, next_cursor, has_more
List a Sume schedule's runs with limit 1-100 (default 50), then pass next_cursor back as cursor until has_more is false. A forged cursor is a 400. Python loop.
- Sume schedule vanity URL: store the aut_ id, not handle/slug
A Sume schedule can be run at /v1/actions/{handle}/{slug}/runs, but renaming either part changes the path. Store the aut_ id; an old handle resolves 90 days.
- Sume SDK 429 retry-after is capped at 60 seconds: what follows
createSumeClient waits at most 60 seconds per retry, with 20 percent jitter and 2 retries by default. What that means for a long retry-after and a fix.
- Sume SDK error code unknown_error and a null requestId
When the response body is not a Sume error envelope, the SDK falls back to code unknown_error with no request id. What it means and what to log instead.
Written by Sume