Formats

Create an AI video workflow via API: a Sume Format and its SKILL.md

Create a Sume Format with POST /v1/formats, then write its SKILL.md recipe through the Contents API. The fields, the slug rules, and the errors to handle.

5 min readSume
All posts

To create an AI video workflow over the Sume API, send POST /v1/formats with a slug. That opens a new Format in your API key's workspace with a minimal SKILL.md, and you then replace that file with your recipe through the Contents API. Your backend calls the result at POST /v1/formats/{handle}/{slug}/runs.

A Format is a saved recipe that a backend calls by name; What is a Sume Format? covers authoring one in chat instead. The facts below come from Editing a Format package, the Format API page, and the Sume API reference, read on 2026-09-26.

Which workspace does a new Format belong to?

The one your key belongs to. POST /v1/formats needs formats:write, and it has no {handle} in the address, so there is no way to create a Format in somebody else's workspace. A team key creates a team Format that answers at the workspace's handle; a personal key creates one at your own handle.

A key without formats:write gets 403 insufficient_scope. Scopes cannot be patched onto a key, so mint a new one that carries it. Service-account keys get the same 403: they cannot create or edit packages.

Which fields does POST /v1/formats take?

The body describes the Format, not its files. Package files go through the Contents API, so they follow one set of rules no matter who wrote them.

From the createFormat schema in the Sume API reference and Editing a Format package, read 2026-09-26.
FieldRules
slugRequired. 1–64 characters, lowercase, matching ^[a-z0-9][a-z0-9._-]*$. Unique within your workspace; it is the {slug} half of the Format's address.
titleUp to 80 characters. The display name in the Formats library. Defaults to the slug.
descriptionUp to 1024 characters, one line only. Written into the seed SKILL.md frontmatter, which the catalog reads the description back from. Defaults to a placeholder.
auto_initDefaults to true and commits a minimal valid SKILL.md. false is a 400: every package must contain SKILL.md, so there is no empty Format.

How do I create a Format and write its recipe?

Three calls. The create answers 201 with the new Format: its skl_… id, handle, slug, version, package_sha, contents_url, and vanity_invoke_url. Keep package_sha and contents_url: the first is the If-Match precondition for your next write, the second is where to send it. Replacing the seed SKILL.md is the intended next call, and because that file already exists, the replace needs its blob sha from a read.

# 1. Open the Format in your key's workspace
curl -sS -X POST "https://api.sume.com/v1/formats" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slug":"plate-shots","title":"Plate shots","description":"Studio plate photography."}'

# 2. Read the seed SKILL.md for its sha
curl -sS "https://api.sume.com/v1/formats/acme/plate-shots/contents/SKILL.md" \
  -H "Authorization: Bearer $SUME_API_KEY"

# 3. Replace it: content is the whole new file, base64-encoded
curl -sS -X PUT "https://api.sume.com/v1/formats/acme/plate-shots/contents/SKILL.md" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "If-Match: $PACKAGE_SHA" \
  -H "Content-Type: application/json" \
  -d '{"message": "write the recipe", "content": "LS0tCm5hbWU6IHBsYXRlLXNob3Rz…", "sha": "0ee8…"}'

What must the Format package contain?

The package rules are checked before anything is committed, and a rejected package commits nothing. The ones a first write meets:

  • SKILL.md sits at the package root, and its frontmatter name must equal the Format's slug.
  • Other files live at the root or one directory deep under references/ or agents/, as .md, .json, .yaml, .yml, or .txt.
  • A rejected path answers skill_path_invalid and spells the whole allowlist back, so one rejection is enough to fix the name.
  • Each write returns the new commit.tree.sha (the next If-Match value) and version. Edit Sume Format files with If-Match covers multi-file commits, and how to write a SKILL.md recipe covers what goes in it.

Which errors can the create return?

The first four are on the docs pages. The last two are current behavior that the docs pages do not list.

  • 409 skill_slug_taken: your workspace already has a Format with that slug. Creating never overwrites; pick another.
  • 409 skill_slug_reserved: a Format by Sume holds that slug globally.
  • 503 format_git_unavailable: package history could not be opened. The repository is opened before the catalog row, so no Format was created.
  • 403 insufficient_scope: the key lacks formats:write, or it is a service-account key.
  • 400 skill_slug_invalid for the reserved slugs runs, bulk-runs, and grants, which would collide with API routes.
  • 400 skill_limit_exceeded when the user who owns the key already owns 50 custom Formats. The cap counts that user's Formats, not the workspace's.

Can I start from an existing Format instead?

Yes. Fork a Format by Sume in the Format library when you want to change one; your copy is addressed as {your_handle}/{slug}. You can also author a Format in the Agents dashboard or in chat.

However it was made, call it with POST /v1/formats/{handle}/{slug}/runs. A Format you have never run over the API may read status: inactive and api_trigger_enabled: false until its first run, and still runs, so do not gate your integration on those fields.

Sources

Related posts

Written by Sume