POST /v1/formats: skill_slug_taken, skill_slug_reserved, 503
Creating a Format over the API can return 409 for a taken or reserved slug and 503 format_git_unavailable. What each means, and what to keep from the reply.

POST /v1/formats can fail three ways beyond auth: 409 skill_slug_taken when your workspace already uses the slug, 409 skill_slug_reserved when a Format by Sume holds it globally, and 503 format_git_unavailable when package history could not be reached, in which case no Format is created.
These come from Editing a Format package, read on 2026-10-02.
What does the create call need?
It needs formats:write, and the Format is created in your key's workspace. There is no handle in the address, so you cannot create one in somebody else's. Service-account keys cannot create or edit packages and fail with 403 insufficient_scope.
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."}'What are the three failures?
Creating never overwrites, so a taken slug is always a 409 and your existing Format is untouched.
| Status | error.code | Meaning | Do |
|---|---|---|---|
| 409 | skill_slug_taken | Your workspace already has that slug | Pick another slug |
| 409 | skill_slug_reserved | A Format by Sume holds it globally | Pick another slug |
| 503 | format_git_unavailable | Package history could not take the commit | Retry; nothing was saved |
| 403 | insufficient_scope | Missing formats:write, or a service-account key | Mint a user key with the scope |
Why is a 503 safe to retry?
The repository is opened before the catalog row. If history cannot be reached the call fails and no Format exists, rather than leaving one whose commits nobody can resolve. A write either commits or fails; there is no path where the Format changes but the commit does not exist.
What do I keep from a successful reply?
Keep package_sha and contents_url. The first is the If-Match precondition for your next write, and the second is where to send it. The reply also carries handle, slug, version and vanity_invoke_url, the address you will call with POST .../runs.
auto_init defaults to true and commits a minimal valid SKILL.md, so the Format is readable and writable at once. Passing false is a 400, because every package must contain SKILL.md. The body does not take package files; use the Contents API for those.
What next?
Replace the starter SKILL.md with a real recipe, then call the Format. The Format's version bumps on every edit, and a run's receipt format.version records which one ran. Renamed handles keep resolving for 90 days.
A create-then-edit sequence
Do not gate your integration on polling status or api_trigger_enabled first. A Format never run over the API may read inactive until its first run and still runs.
- Create the Format and keep
package_shaandcontents_urlfrom the reply. - Read the starter
SKILL.mdand keep itsshafor the replacement write. - Commit your recipe with the file
sha, sending the package sha asIf-Match. - Call the Format at its
vanity_invoke_urlwith anIdempotency-Keyderived from your own record.
How do I pick a slug that will not collide?
Reserved slugs belong to Formats by Sume, the first-party catalog that answers at the sume handle. If your slug is generic, such as a common product-video name, expect a reserved or taken answer and add a prefix that names your use case or brand.
The workspace check is per workspace. The same slug can exist in another workspace, because a Format is addressed as {handle}/{slug}. A 404 format_not_found on a later call usually means you are holding the other workspace's key.
What does a successful create not give me?
It does not run anything. Creating a Format opens its package; the recipe is the starter file until you replace it. To call it you also need the API call trigger enabled; a Format never run over the API may read inactive until its first run, and still runs.
Sources
Related posts
More in Formats
- Format bulk queue: no queue webhook, no cancel-queue endpoint
A Sume bulk queue has no webhook and no cancel call. Poll the queue, put webhooks on items, and cancel the child runs one by one with their run ids.
- Format Contents API: read the whole package, commit many files at once
Read a Sume Format package with ?recursive=1 and write several files as one commit and one version bump. A change set, not the package; deletes stay separate.
- Format output rejects a scene clip in the final video field
A Format schema with scenes and a full_video field fails when full_video reuses a scene file. The exact two-part rule, and how to report an unassembled show.
- Why your order_id comes back null in a Sume structured output
If a Sume run's filled_by is projection, the fallback never sees your input or instruction, so an order_id you sent comes back null. Keep ids on your side.
Written by Sume