Route tickets with Clef, then pick a Sume Format by its io profile
Clef routes a ticket by team and urgency. Then read GET /v1/formats/{handle}/{slug} for io.input_kind before you call POST .../runs. A short Python router.

Let the decision model choose a category, keep a small table that maps each category to a Format, and read the Format's io profile before you send a run. Cloudflare's post shows Clef taking a support message and returning urgency and a team with probabilities. Sume's side starts at GET /v1/formats/{handle}/{slug}, which returns io.input_kind (url, text, image or product) and io.output_kind (video, image or text) so that you know what input the Format expects.
Why read io first
The io field is the only declared contract between a Format's author and its callers, so a router that checks it fails early with a clear message instead of starting a run that reads nothing. Both io and showcase are null for Formats saved before registration existed. That means "not declared", so fall back to the Format's description.
| Step | Call | What you read |
|---|---|---|
| Decide | Clef with your question | Category and probability |
| Look up | GET /v1/formats/sume/{slug} | io.input_kind, io.output_kind, description |
| Run | POST /v1/formats/sume/{slug}/runs | 202 receipt with usage cap |
| Wait | GET status_url | status, next_action |
A router in Python
Any key with formats:write can call a catalog Format at the reserved sume handle. The run, its media and its spend belong to that key. Put the customer's text in input, not in instruction, because Sume hands input to the agent as caller data and not as instructions.
import os
import requests
API = "https://api.sume.com/v1"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
ROUTES = {"product_demo": "sume-product-usage-demo", "promo": "sume-product-commercial"}
def run_for(category: str, ticket_id: str, text: str) -> str:
slug = ROUTES[category]
fmt = requests.get(f"{API}/formats/sume/{slug}", headers=H, timeout=30)
fmt.raise_for_status()
io = fmt.json()["data"].get("io")
if io and io["input_kind"] not in ("text", "product", "url"):
raise ValueError(f"{slug} takes {io['input_kind']}")
r = requests.post(
f"{API}/formats/sume/{slug}/runs",
headers={**H, "Idempotency-Key": f"{ticket_id}-{slug}-v1"},
json={"input": {"message": text}, "generation_spend_cap_usd": 5},
timeout=30,
)
r.raise_for_status()
return r.json()["data"]["id"]
Keep the table honest
Unknown handles, unknown slugs and slugs that are not in the catalog all answer 404 format_not_found. Read the catalog page for the slugs that exist today, and do not assume that a routing table written last month is still complete.
Sources
Related posts
More in Formats
- One Idempotency-Key, two Sume Formats: you start two runs
A Sume idempotency key is scoped to one Format, so one key sent to two Formats starts two paid runs. Build keys from order, Format and version.
- Client needs your Format: a grant, or a key from your workspace?
A grant bills the client and keeps the roster on your side; a team key you mint bills you. Pick the grant unless you intend to resell the output.
- Shared Format 409 format_inactive: the owner's switch hits partners
format_inactive and format_api_trigger_disabled are set on the owner's API tab and apply to every caller, including workspaces the Format was shared with.
- Shared Format run stuck queued: whose concurrency limit applies?
A partner's run on your shared Format uses the partner's concurrency slot, so the partner's plan limit and queue decide when it starts, not yours.
Written by Sume