Is there an asset library API for AI images and videos?

Sume has no folders or tags. Your library is completed jobs plus durable media.sume.com artifacts, which you list, label by Idempotency-Key, and download.

5 min readSume
All posts

Sume has no folder-and-tag asset library for generated images and videos that I could find in the docs. What it gives you is three pieces you can build one from: completed jobs listed by GET /v1/jobs, durable media.sume.com artifacts on each result, and a separate sume assets set of commands for input files. Labelling is up to you, and the cleanest label is the Idempotency-Key you send on submit.

This post lays out what each piece holds and how to query it, so you can decide whether that is enough or whether you should mirror the files into your own storage.

What counts as an asset on Sume?

Completed jobs can include artifact objects: an id like artf_..., a url on media.sume.com, a type and a content_type. The API schema also carries size_bytes, width, height, duration_ms and checksum_sha256, each nullable. Sume mirrors generated outputs into Sume-owned URLs before exposing them, and the docs tell integrations to store the Sume URL, not the raw provider URL.

Separately, the CLI has sume assets list, get, create --source-url, upload-url, complete, download-url and download. These register or upload first-party input files when a workflow needs asset ids. For normal Image, Video and Avatar requests the docs say to prefer public HTTPS URLs and skip the asset lifecycle.

How do I list everything I generated?

GET /v1/jobs returns your workspace's jobs newest first, capped at 100 per page. Filters are type, status (the job lifecycle values), limit (1 to 100), scope, run_id and thread_id. When data.next_cursor is present, pass it back as starting_after. An unknown query parameter is a 400 unknown_parameter, not a silently unfiltered page, so a typo in a filter name fails loudly.

The docs make one more point worth keeping: do not read identity off array position, because newest-first is not your submission order once retries happen. Each row carries the idempotency_key it was created with, and that is the column to join your own labels on.

import os, requests

H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
params = {"limit": 100, "status": "completed"}
rows = []
while True:
    page = requests.get("https://api.sume.com/v1/jobs", headers=H, params=params)
    page.raise_for_status()
    data = page.json()["data"]
    rows += data["jobs"]
    if not data.get("next_cursor"):
        break
    params["starting_after"] = data["next_cursor"]

film = [j for j in rows if (j.get("idempotency_key") or "").startswith("film-42-")]
print(len(rows), "jobs;", len(film), "belong to film-42")

How do I label assets so they are findable?

That prefix convention is the whole trick. It costs nothing, survives retries because a retried submit with the same key returns the original job, and it lets you rebuild an index from GET /v1/jobs if your own database is lost.

Where each kind of label can live on Sume (docs and API schema, read 2026-10-02)
NeedWhereNotes
Name a shotIdempotency-Key at submit, e.g. film-42-shot-03-take-2Returned on each job row; a replay returns the original job
Group a filmCommon key prefix, filtered client-sideThe list API has no key or prefix filter in its documented query
Filter by kindtype query parameterRead the exact type string from a row you already have
Find failed workstatus query parameterUses the documented job status values
Store the filemedia.sume.com artifact URL and artf_ idDownload what you need to keep; no retention period is documented
Record the recipeYour own database row per job idPrompt, model, input URLs and key are not browsable by folder

Where is this approach weak?

There is no server-side search by prompt, no tags, no folders and no shared-collection permissions in the documented API. Listing is by job, so a film made of eight clips is eight rows you group yourself. A prefix filter happens on your side after paging, which is fine for thousands of jobs and clumsy for hundreds of thousands.

For files you want to keep, download them. The CLI does it in one line: sume jobs download <job_id> --output-dir ./out writes completed media artifacts to a directory, and sume jobs list --agent --json gives the same list from a terminal. For a mirror into your own bucket, loop over finished rows and copy each url.

If you need to bring outside media in, import it first (POST /v1/media-imports) or register it with sume assets create --source-url ...; the video tools that take a media.sume.com URL refuse off-host links. The post comparing flat asset libraries goes into that difference.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume