Model fallback & cost control
12 minRun a cheap model for the easy cases and escalate to a stronger one only on failure, attribute the spend per customer, and cap that customer with a budget. Resilience and cost control in a few headers.
- •
A Ringside API key exported as
FC_API_KEY - •
A customer id (create one, or let the FC-Customer header create it on the fly)
Try cheap first, escalate on failure
Pass model as an array and Ringside walks it: it tries the first model, and only if that fails (a provider 5xx, an outage, or a schema-validation failure) does it move to the next. So you run the cheap model for the easy majority and reach for the expensive one only when you have to, without writing retry logic yourself.
curl https://api.fightclub.pro/v1/chat/completions \
-H "Authorization: Bearer $FC_API_KEY" -H "Content-Type: application/json" \
-d '{
"model": ["fc:openai/gpt-4o-mini", "fc:anthropic/claude-sonnet-4"],
"messages": [{"role":"user","content":"Summarize this contract clause: ..."}]
}'See which model actually served
The response headers tell you what happened, so a cascade is never a black box. Read them if you want to log escalations or alert when the cheap path is failing often.
// response headers on a cascaded call: X-Ringside-Model-Used: fc:anthropic/claude-sonnet-4 X-Ringside-Models-Tried: fc:openai/gpt-4o-mini,fc:anthropic/claude-sonnet-4 X-Ringside-Fallback-Triggered: true
A cascade cannot be combined with stream:true or an Idempotency-Key (you get a clear 400). Pick streaming OR fallback per call.
Attribute the spend to a customer
Add the FC-Customer header so the cost lands against a specific end-user instead of a generic bucket. Now you know what each customer costs, which is the basis for both internal cost control and billing them.
curl https://api.fightclub.pro/v1/chat/completions \
-H "Authorization: Bearer $FC_API_KEY" \
-H "FC-Customer: cus_42" \
-H "Content-Type: application/json" \
-d '{"model":["fc:openai/gpt-4o-mini","fc:anthropic/claude-sonnet-4"],
"messages":[{"role":"user","content":"..."}]}'Cap a customer with a budget
Give the customer a budget with monthly_budget_usd and Ringside enforces it. Once their attributed spend would exceed it, calls tagged with that customer return 402 customer_budget_exceeded instead of running up your bill. Your wallet still has money; this is a per-customer ceiling.
# set (or raise) a monthly budget on the customer
curl -X PATCH https://api.fightclub.pro/v1/customers/cus_42 \
-H "Authorization: Bearer $FC_API_KEY" -H "Content-Type: application/json" \
-d '{"monthly_budget_usd": 50}'
# from then on, a call for cus_42 over budget returns:
# HTTP 402 { "error": { "code": "customer_budget_exceeded", ... } }The field is monthly_budget_usd. budget_usd is not a recognized field — send that and it is silently dropped, no budget is set, and the cap never fires. Handle the 402 by showing the customer an upgrade prompt or raising their budget. A 402 with code wallet_empty is different: that is your whole balance gone, top it up. Always branch on the error code, not the message.