Developers

Sume job vs run: generation jobs and Format, Action, Agent runs

A Sume job is one generation request tracked at /v1/jobs; a run is one agent turn from a Format, schedule, or Agent Completion. Ids, webhooks, and waits differ.

5 min readSume
All posts

In the Sume API, a job is one generation request from a model endpoint such as POST /v1/videos or an Avatar route, tracked at /v1/jobs/{id}. A run is one agent turn started by a Format, a schedule (the Actions API), or an Agent Completion, tracked under /v1/format-runs, /v1/action-runs, or /v1/agent-runs. Their ids, statuses, webhooks, and wait helpers differ, and a job id and a run id are not interchangeable.

The comparison below draws on Sume's Jobs and results, API reference, Run webhooks, and Waiting for runs and jobs docs, read on 2026-09-26.

What is the difference between a job and a run?

Side by side, for the calls you make most. The Format run lifecycle itself is covered in Sume Format run lifecycle.

From Jobs and results, the API reference, and Run webhooks, read 2026-09-26.
AspectGeneration jobFormat, Action, or Agent run
Created byA model endpoint: POST /v1/videos, the Avatar routes, the /v1/models/sume/…/runs aliasesPOST /v1/formats/{handle}/{slug}/runs, POST /v1/actions/{action_id}/runs, POST /v1/agent/completions
Idjob_…arun_… for Format runs and API-triggered Action runs (the schedule docs show run_… on a scheduled one), agrun_… for Agent Completions
Read atGET /v1/jobs/{id}, plus /status, /result, and /eventsGET /v1/format-runs/{run_id}, /v1/action-runs/{run_id}, or /v1/agent-runs/{run_id}, plus /status and /result
Terminal statusescompleted, failed, canceledThe same, plus skipped on Format and Action runs
Delivery choicemode: async, sync, subscribe, or webhookcommunication.mode: async or webhook
Webhook eventsjob.completed, job.failed, job.canceledformat.run.terminal, action.run.terminal, agent.run.terminal, on completed or failed only
CancelOnly before generation starts; then 409 job_generation_already_startedIdempotent POST …/cancel; stops a run that is queued or processing
TypeScript waitwaitForJobwaitForRun with family, or subscribeFormatRun

How do I tell which one I created?

Look at the route you called and the response. A job submit envelope carries request_id, which is the job id, and POST /v1/videos answers with an id that is the job id. A run create returns a receipt whose object is format.run, action.run, or agent.run, with a status_url on its own family's route. Read each one where it lives:

# A job, from POST /v1/videos or an Avatar route
curl https://api.sume.com/v1/jobs/$JOB_ID/status \
  -H "Authorization: Bearer $SUME_API_KEY"

# A Format run: its own family route, not /v1/jobs
curl https://api.sume.com/v1/format-runs/$RUN_ID \
  -H "Authorization: Bearer $SUME_API_KEY"

How are runs and jobs related?

A run is one agent turn, so its terminal webhook fires once, however many clips or images the turn produced. Progress inside the turn lives at the generation-job layer, whose webhooks fire per job as each one completes.

For cost, GET /v1/usage takes run_id to sum what one Format, Action, or Agent run cost, the agent's own turns included, or job_id to sum one generation job.

Which webhook will I get?

Jobs and runs send different events and payloads, but the signature scheme is identical, so one verifier covers both: route on event. Dedupe job deliveries on job_id and run deliveries on the envelope's request_id, which equals run_id. Signed webhooks for video runs covers verification.

One difference catches people: a job reaching canceled sends job.canceled, but a canceled or skipped run never delivers a webhook. Trust the cancel response, or the create response for a skip.

Which mistakes does the split cause?

Most bugs here come from treating the two as one resource:

  • Polling /v1/jobs with a run id. Actions have their own run resource and do not appear under /v1/jobs, and an Action or Format run id does not resolve on /v1/agent-runs.
  • Looking for GET /v1/format-runs. There is no cross-Format run list: list runs per Format, or keep your own index of the run ids you stored. Jobs do have a list, GET /v1/jobs.
  • Sending mode: "subscribe" to a run. communication.mode has no subscribe value, and supplying webhook_url is what arms delivery.
  • Expecting to cancel a job mid-generation. Job cancel succeeds only before generation work starts, while a run stays cancelable through processing.
  • Calling waitForRun with a job id. Use waitForJob for jobs; Wait for jobs and runs in the Sume SDK covers both helpers.

Sources

Related posts

Written by Sume