List Formats API: find and address Sume Formats by handle or id
GET /v1/formats lists the Formats your key can call. Address one by {handle}/{slug} or by its permanent skl_ id, and list its runs newest first.

To list Sume Formats over the API, send GET /v1/formats with a key that has formats:read. It returns the Formats your key's workspace owns plus the first-party catalog, in keyset pages. A row for one of your Formats carries two addresses: vanity_invoke_url at {handle}/{slug}, and invoke_url at the Format's permanent skl_… id.
The facts below come from Find your Formats, Address a Format, and List runs for a Format, read on 2026-09-26. What each catalog Format makes is covered in Ready-made Formats for product video.
How do I list the Formats my key can call?
Call GET /v1/formats. limit is 1–100 and defaults to 50. While has_more is true, pass next_cursor back as cursor for the next page.
Visibility follows the key. A personal key lists your personal Formats; a team key lists that workspace's Formats, for every member; neither lists the other's. A Format outside your key's workspace is 404 format_not_found, the same answer as an id that does not exist, so if a Format you expect is missing, you are holding the other key.
curl -sS "https://api.sume.com/v1/formats?limit=50" \
-H "Authorization: Bearer $SUME_API_KEY"Which address should I call and store?
The {handle}/{slug} and {format_id} shapes resolve to the same Format and run the same pipeline: same body, headers, idempotency, caps, and receipt. The receipt's format.id is always the opaque skl_… id, whichever shape you used.
| Shape | Example | Use it when |
|---|---|---|
{handle}/{slug} | POST /v1/formats/acme/product-promo/runs | Every new integration. It is the address the Format detail page shows. |
{format_id} | POST /v1/formats/skl_…/runs | A stored URL that must survive a handle or slug rename. Permanent, identical behavior. |
sume/{slug} | POST /v1/formats/sume/sume-product-commercial/runs | The Formats by Sume catalog. Any key with the scopes may call it; the run belongs to that key. |
What happens to stored URLs when a handle is renamed?
handle is the owning workspace's handle for a team Format and your own for a personal one. invoke_url, the opaque skl_… path, is permanent across renames, so persist it when a stored URL must survive a handle or slug change. A renamed handle keeps resolving for 90 days. The API reference calls vanity_invoke_url a convenience: renaming either half changes it.
Why does a Format I expect return 404?
An unknown handle, an unknown slug, and a handle you cannot see all answer the same 404 format_not_found. So do an archived Format, one outside your key's workspace, and a shared Format whose grant is still pending or was removed. Two answers are not 404s:
403 insufficient_scope: the key lacksformats:readorformats:write. A missing scope is never404 format_not_found.403 workspace_key_required: right team, wrong key. You are a member of the team workspace but sent a personal key; see How Sume API keys work.
How do I read one Format before calling it?
Read it by address with GET /v1/formats/{handle}/{slug}, or by id with GET /v1/formats/{format_id}. The docs cookbook uses this as a preflight for a settings screen: confirm the address resolves for your key, what the Format takes, and its cap. The recipe body is deliberately not in the response.
status and api_trigger_enabled must both allow API runs, but a Format you have never run over the API may read inactive / false until its first run and still runs. Do not gate your integration on them. To hand a partner the curl, scopes, and poll loop for one Format, share its call sheet at https://docs.sume.com/formats/{handle}/{slug}; it shows nothing from the Format's body.
curl -sS "https://api.sume.com/v1/formats/acme/product-promo" \
-H "Authorization: Bearer $SUME_API_KEY" \
| jq '.data | {id, handle, slug, version, status, api_trigger_enabled, io,
cap_usd: (.generation_spend_cap_usd_micros / 1000000), vanity_invoke_url}'How do I list a Format's runs?
GET /v1/formats/{handle}/{slug}/runs, or its opaque twin GET /v1/formats/{format_id}/runs, returns runs newest first. limit is 1–100 and defaults to 20. The cursor is opaque and keyset over (created_at, id), so runs created while you page do not shift rows; a cursor that is not Sume's is 400 invalid_request. A Format never run over the API returns an empty list, not a 404.
- There is no
GET /v1/format-runs: list per Format, or keep your own index of the run ids you stored at create. - Read one run at
/v1/format-runs/{run_id}. The Format path only creates and lists. GET /v1/format-runs/{run_id}/messagesdoes not exist: the conversation is not published over the API.
Sources
Related posts
Written by Sume