Shotstack render statuses vs Sume job statuses: a map

Shotstack renders go queued, fetching, rendering, saving, done or failed. Sume jobs go queued, processing, completed, failed or canceled. Map them in code.

5 min readSume
All posts

Shotstack render statuses run queued, fetching, rendering, saving, then done or failed. Sume's job statuses are queued, processing, completed, failed and canceled, and the status endpoint also carries two booleans, terminal and result_ready, that tell you when to stop and when to read.

Shotstack's list is from its v1 API reference; Sume's is from Jobs and results.

How do the states line up?

Shotstack exposes the pipeline stages: assets are fetched and cached, then rendered, then the final file is saved. Sume collapses the running part into one processing state, described as running or being finalized. The cancel state is the other difference: the Shotstack list I read has no cancelled status, while Sume has canceled.

Status map, read 2026-10-02
ShotstackSume `sume_status`Terminal
queuedqueuedNo
fetchingprocessingNo
renderingprocessingNo
savingprocessingNo
donecompletedYes
failedfailedYes
no equivalent listedcanceledYes

What else differs when you submit?

Shotstack's render call is POST /edit/{version}/render with an Edit document and an optional callback. Video assets are preprocessed automatically, and "transcode": true forces it. Sume has no transcode flag: its media endpoints take only a workspace media.sume.com artifact, so you import first with POST /v1/media-imports, and the server compiles ffmpeg itself. Sending codec, crf, filtergraph and similar fields to Timeline returns a 400.

Shotstack can also send output to destinations such as S3, Google Cloud Storage, Google Drive, Mux or Vimeo. Sume's docs say results are mirrored into Sume-owned media.sume.com URLs and you store that URL; no destination option is documented.

What should your poller read on Sume?

Poll GET /v1/jobs/:id/status and stop when terminal is true. Then read GET /v1/jobs/:id/result only if result_ready is true; a result read on an unfinished job returns 409 job_not_completed. A failed or canceled job's reason is on the job record, not the result.

TERMINAL = {"completed", "failed", "canceled"}
SHOTSTACK_TO_SUME = {
    "queued": "queued",
    "fetching": "processing",
    "rendering": "processing",
    "saving": "processing",
    "done": "completed",
    "failed": "failed",
}


def is_done(sume_status: str) -> bool:
    return sume_status in TERMINAL


assert SHOTSTACK_TO_SUME["saving"] == "processing"
assert is_done("canceled")

Does the stage detail matter?

If you show users a progress label such as downloading assets, you lose that detail on Sume's processing. If you only branch on done or failed, the map above is enough. Keep a polling fallback even when you use a webhook: Sume sends terminal events only, and a failed delivery does not change the job's real state.

What other differences show up in a port?

Shotstack's Edit document is a JSON timeline of tracks and clips with many asset types, including text, rich text, shapes, captions, text-to-speech and HTML. Sume's Timeline 1.0 is narrower: one audio spine plus ordered video slots, six transition types and fit modes. Do not expect to port a layered Shotstack template one to one; compose, trim and filter are separate calls.

Billing differs as well. Sume prices Timeline at $0.10 per ceil output minute and a trim at $0.02 per job, confirmed through GET /v1/catalog. For Shotstack pricing see the earlier comparison linked below, since this page does not repeat it.

  • Shotstack has asset types Sume does not list, such as text and shape assets.
  • Sume transitions: fade, wipeleft, wiperight, slideup, slidedown, dissolve.
  • Sume has no cancelled-style status on Shotstack's list.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume