/v1/videos status expired: in the enum, never sent by Sume

The /v1/videos status enum includes expired for OpenRouter compatibility, but Sume never emits it. Handle it as terminal anyway; five other statuses occur.

4 min readSume
All posts

GET /v1/videos/{id} can return pending, in_progress, completed, failed or cancelled. The enum also holds expired, which Sume never emits: the API does not expire jobs. Write your poll loop so an unknown or expired status stops the loop instead of spinning forever.

Status mapping

Sume maps its internal job statuses to the OpenRouter-shaped values like this.

Sume /v1/videos status mapping, read 2026-10-05
Sume job.status/v1/videos statusTerminal?
queuedpendingNo
processingin_progressNo
completedcompletedYes, download the video
failedfailedYes, read error
canceledcancelledYes (note the spelling change)
not emittedexpiredTreat as terminal if you ever see it

Two spelling traps

Two details trip people up. Sume spells the internal state canceled, but /v1/videos returns cancelled. And expired exists only so that clients generated from the OpenRouter schema parse the field without error. A strict enum in your own types should include it.

A safe poll loop

This loop treats every non-running status as terminal and never loops on a value it does not know.

import asyncio, os
import httpx

RUNNING = {"pending", "in_progress"}

async def main():
    headers = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
    async with httpx.AsyncClient(base_url="https://api.sume.com", headers=headers) as c:
        job = (await c.post("/v1/videos", json={
            "model": "sume/auto",
            "prompt": "A paper boat drifting down a rain gutter",
        })).json()
        while True:
            await asyncio.sleep(30)
            st = (await c.get(job["polling_url"])).json()
            if st["status"] in RUNNING:
                continue
            print(st["status"], st.get("error"), st.get("unsigned_urls"))
            break

asyncio.run(main())

Polling versus webhooks

The Sume docs suggest a moderate poll interval of about 30 seconds. You can also pass callback_url (HTTPS) and receive a signed webhook on a terminal state.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume