Prefer Swagger UI? Click hereThe same API in the classic OpenAPI explorer.
POST/v1/chat/completions

Chat Completions

Creates a chat completion for the given messages. Streaming supported via SSE. Pass model as an array for cost-aware fallback (e.g. ["fc:openai/gpt-4o-mini", "fc:openai/gpt-4o"]) — Ringside walks the chain on 5xx / schema-validation failure and surfaces the winner via X-Ringside-Model-Used.

Request
HTTP
POST
URL
/v1/chat/completions
Auth
api_key, client_token
Try it
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","messages":[{"role":"user","content":"Hello"}]}'

# Cost-aware fallback: try cheap first, escalate on failure
curl https://api.fightclub.pro/v1/chat/completions \
  -H "Authorization: Bearer $FC_API_KEY" \
  -d '{
    "model": ["fc:openai/gpt-4o-mini", "fc:openai/gpt-4o"],
    "messages": [{"role":"user","content":"Hello"}]
  }'
# Response headers indicate which model served:
#   X-Ringside-Model-Used: fc:openai/gpt-4o
#   X-Ringside-Models-Tried: fc:openai/gpt-4o-mini,fc:openai/gpt-4o
#   X-Ringside-Fallback-Triggered: true

Example response

{
  "id": "chatcmpl_8Xb1cD2eF",
  "object": "chat.completion",
  "created": 1782300000,
  "model": "openai/gpt-4o-mini",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": { "role": "assistant", "content": "Hello, good to meet you." }
    }
  ],
  "usage": { "prompt_tokens": 9, "completion_tokens": 7, "total_tokens": 16 }
}
// Response headers also carry:
//   X-Ringside-Model-Resolved: openai/gpt-4o-mini
//   X-Ringside-Cost-Usd: 0.0000042

A representative 200 body. Ids and timestamps are illustrative.

Body parameters

NameTypeDefaultDescription
model*string | string[]Prefixed model ref (e.g. "fc:openai/gpt-4o-mini"). Must start with fc:, match:, slot:, or dyn: — a bare name like "gpt-4o" returns 400 invalid_model_ref. Append @<region> for data residency (e.g. fc:openai/gpt-4o@eu). Pass an array to enable a cost-aware cascade: the first model is tried, escalating to the next on 5xx / upstream_unavailable / response_schema_validation_failed. An array with stream:true is rejected 400 fallback_with_stream_unsupported.
messages*arrayList of message objects, each { role, content }. role is system | user | assistant | tool.
streambooleanfalseWhen true the response is an SSE stream of chat.completion.chunk objects terminated by data: [DONE]. Cannot be combined with a model:[] cascade or a response_format json_schema.
stream_optionsobjectoptional{ include_usage: true } appends a final chunk carrying the usage object. Only meaningful with stream:true.
max_tokensintegeroptionalCap on generated tokens.
temperaturenumberoptionalSampling temperature, 0-2. Higher is more random.
top_pnumberoptionalNucleus sampling, 0-1. Use this or temperature, not both.
toolsarrayoptionalOpenAI-compatible function tool definitions: [{ type: "function", function: { name, description, parameters } }].
tool_choicestring | objectoptionalauto | none | required, or { type: "function", function: { name } } to force a specific tool.
response_formatobjectoptional{ type: "json_object" } for loose JSON, or { type: "json_schema", json_schema: {...} } for strict output enforced across all 19 providers — non-native models run a runtime ajv loop with up to 2 re-prompts; persistent failure is 422 response_schema_validation_failed. Cannot be combined with stream:true (400 streaming_with_schema_fallback_unsupported).
moderationstringnonenone | pre | post | pre_and_post. pre screens the prompt before spending, post screens the completion. A flagged call returns 400 moderation_flagged.
prompt_cachestringoffauto | off. auto lets Ringside reuse provider-side prompt caches where supported.
cache_controlobjectoptional{ type: "ephemeral", ttl?: "5m" | "1h" } marks the response cacheable by Ringside's own response cache. See also the FC-Cache request headers.
userstringoptionalOpaque end-user id passed through to providers that accept it.

* required.

Headers

HeaderDirDescription
FC-Customerreq →Attribute the call to a customer (by id or ext:<external_id>) for budget enforcement + reporting. Auto-creates the customer if new.
X-FC-Billable-Amountreq →Override the metered amount in micro-dollars (for resold / marked-up pricing).
FC-Session-Idreq →Group related calls under one session id in reporting.
FC-Property-*req →Arbitrary dimension tags (e.g. FC-Property-Team: growth) surfaced in usage breakdowns.
FC-Tag-*req →Free-form labels attached to the usage record.
idempotency-keyreq →De-dupe retries (24 h replay window, scoped per dev + customer). Rejected with a cascade (400 fallback_with_idempotency_unsupported).
FC-Cache / FC-Cache-TTLreq →Opt the call into Ringside's response cache and set its TTL.
X-Request-Id← resUnique id for this request; quote it in support tickets.
X-Ringside-Model-Resolved← resThe concrete fc: model a match:/slot:/dyn: ref resolved to.
X-Ringside-Model-Used / -Models-Tried / -Fallback-Triggered← resOn a cascade: the winning model, the full chain tried, and whether fallback fired.
X-Ringside-Model-Newer-Available← resSet when a newer model in the same family exists.
X-Ringside-Dynamic-Profile / -Reason← resFor dyn: refs: which profile was picked and why.
X-Ringside-Wallet-Balance / -Wallet-Deducted← resRemaining wallet balance and the amount this call deducted.
X-RateLimit-Remaining← resRequests left in the current window.
FC-Cache-Status / -Cache-Key / -Cache-Age← reshit | miss, the cache key, and age in seconds when served from cache.

Response fields

NameTypeDescription
idstringCompletion id (chatcmpl-*).
objectstring"chat.completion" (or "chat.completion.chunk" when streaming).
createdintegerUnix timestamp.
modelstringThe model that served the request.
choicesarray[{ index, message: { role, content, tool_calls? }, finish_reason }].
usageobject{ prompt_tokens, completion_tokens, total_tokens }.

Errors

  • 401missing_tokenNo Authorization header was sent.
  • 401invalid_auth_schemeThe scheme was neither Bearer nor Client.
  • 401invalid_token_formatA Bearer token not prefixed ko_.
  • 401invalid_tokenThe API key is unknown, revoked or expired.
  • 403insufficient_scopeThe key is valid but lacks the required scope.
  • 400invalid_jsonRequest body is not valid JSON.
  • 400missing_modelmodel is absent.
  • 400missing_messagesmessages is absent or empty.
  • 400invalid_model_refmodel is not a fc:/match:/slot:/dyn: ref.
  • 400invalid_model_for_chatThe model resolved to one that cannot do chat.
  • 400moderation_flaggedPrompt or completion failed moderation.
  • 400streaming_with_schema_fallback_unsupportedresponse_format json_schema requested with stream:true.
  • 400fallback_with_stream_unsupportedmodel:[...] cascade requested with stream:true.
  • 400fallback_with_idempotency_unsupportedmodel:[...] cascade requested with an Idempotency-Key.
  • 402customer_budget_exceededThe FC-Customer's monthly budget is spent.
  • 402customer_wallet_emptyThe customer's prepaid balance is zero/insufficient.
  • 402wallet_emptyYour developer wallet balance is zero; top up.
  • 422response_schema_validation_failedOutput did not match response_format.json_schema after 2 re-prompts.
  • 429customer_rate_limit_exceededThe customer's rpm cap was hit.
  • 429edge_rate_limit_exceededThe per-IP edge limiter tripped.
  • 429client_token_rate_limit_exceededThe per-client-token rpm ceiling was hit.
  • 429lazy_create_rate_exceededThe customer auto-create ceiling was hit (100/hour or 1000/day).
  • 503platform_not_configuredNo upstream provider key is configured for the resolved model.
  • 503upstream_unavailableProvider errored and no fallback succeeded.

See the full error reference.

Notes

  • ·This endpoint is OpenAI wire-compatible: point the OpenAI SDK at base_url https://api.fightclub.pro/v1 and the only required change is the model ref prefix.
  • ·Spend is metered per call against your wallet, or against the FC-Customer when that header is present. Read X-Ringside-Wallet-Deducted to see the exact charge.
  • ·Streaming uses Server-Sent Events; add stream_options:{include_usage:true} to get a final usage chunk.
  • ·A cascade (model array) is mutually exclusive with both streaming and idempotency keys.

Examples