Chat completions
Create a model response for a conversation. This endpoint is wire- compatible with OpenAI's /v1/chat/completions, so any OpenAI client works unchanged.
Request body
The request is the standard OpenAI chat-completions body. The only field that changes your provider is model.
| Field | Type | Description |
|---|---|---|
| model* | string | A catalog model id (e.g. openai/gpt-5.5) or an auto-router id (bold/auto). See Models. |
| models | string[] | Optional fallback chain. If the primary model (and its providers) fail, the gateway tries each of these in order. See Routing & failover. |
| messages* | array | The conversation so far. Each message has a role (system, user, assistant, or tool) and content (a string or an array of content parts for multimodal input). |
| stream | boolean | When true, tokens are streamed as Server-Sent Events. See Streaming. Defaults to false. |
| max_tokens | integer | Maximum tokens to generate in the response. |
| temperature | number | Sampling temperature. Ignored by reasoning models that disallow it. |
| top_p | number | Nucleus sampling probability mass. |
| stop | string | string[] | Up to several sequences where generation stops. |
| tools | array | Function/tool definitions, OpenAI-shaped. Translated to each provider's native tool format. |
| tool_choice | string | object | Controls whether and which tool the model may call. |
| response_format | object | Constrains the output format: { type: "json_object" } for JSON mode, or { type: "json_schema", json_schema: { ... } } for a schema. See JSON mode & structured outputs. |
| reasoning | object | Controls thinking on reasoning models: { enabled, effort, max_tokens }. Mapped to each provider's own controls; ignored by models without reasoning. See Reasoning control. |
| provider | object | Per-request provider preferences: { order, only, ignore, allow_fallbacks, sort }. Constrain or reorder which providers may serve the request. See Routing & failover. |
| anonymize | boolean | object | Redact PII from the messages before any provider sees them, and (by default) restore it in the response. See Prompt anonymization. |
max_completion_tokens and reject custom sampling - the gateway translates max_tokens and drops unsupported params automatically.Example request
curl https://boldrouter.com/v1/chat/completions \
-H "Authorization: Bearer $BOLD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4.6",
"messages": [
{ "role": "system", "content": "You are concise." },
{ "role": "user", "content": "What is an API gateway?" }
],
"max_tokens": 256
}'Response
A non-streaming request returns a single chat.completion object, identical in shape to OpenAI's:
{
"id": "chatcmpl-mq581fe5",
"object": "chat.completion",
"created": 1780923785,
"model": "anthropic/claude-sonnet-4.6",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "An API gateway is..." },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 58,
"total_tokens": 82,
"completion_tokens_details": { "reasoning_tokens": 12 }
}
}Usage & billing
The usage object reports token counts, taken from the provider's own numbers when available and estimated otherwise. You are billed on these counts at the model's price - see Pricing & billing. Cache hits are reported under prompt_tokens_details.cached_tokens and billed at a discount (Prompt caching). Tokens a model spent thinking are reported under completion_tokens_details.reasoning_tokens. They are already included in completion_tokens and billed as output, the way providers bill them, even though the reasoning itself is not returned. The field appears only when the provider reports it. Even interrupted streams and client disconnects are metered for the partial output produced.
Response headers
Every gateway response carries headers describing how it was routed:
| Field | Type | Description |
|---|---|---|
| x-bold-provider | string | The provider that ultimately served the request. |
| x-bold-model | string | The catalog model id that was resolved. |
| x-bold-route-attempts | string | Comma-separated providers tried, in order. |
| x-bold-fell-back-from | string | Present only when a failover occurred - the provider that failed first. |
| x-bold-cache | string | Whether prompt caching was enabled (on/off). See Prompt caching. |
| x-bold-byok | string | true when served via your own provider key (BYOK). |
| x-bold-files | string | Number of attached files extracted to text, when any. See File & document input. |
| x-bold-anonymized | string | Count of PII entities redacted (the count only, never the values), when anonymize is on. See Prompt anonymization. |
| x-bold-dropped-params | string | Present only when the provider that served the request could not honor a parameter you sent - a comma-separated list of the parameter names. See JSON mode & structured outputs. |
| x-ratelimit-* | string | Per-key rate-limit budget. See Errors & rate limits. |
JSON mode & structured outputs
Constrain the model to emit JSON with response_format, using OpenAI's shape. { type: "json_object" } asks for any valid JSON object; { type: "json_schema" } additionally pins the shape.
curl https://boldrouter.com/v1/chat/completions \
-H "Authorization: Bearer $BOLD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4.1-mini",
"messages": [
{ "role": "user", "content": "Extract the name and age: Ada is 36." }
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person",
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "age"]
}
}
}
}'Provider support
Support differs by provider, so the gateway resolves the parameter against whichever provider serves the request:
| Field | Type | Description |
|---|---|---|
| OpenAI-compatible providers | forwarded | OpenAI, Mistral, xAI, DeepSeek, Perplexity, Z.ai, Moonshot, Qwen, Cohere, Writer and the other OpenAI-shaped providers receive response_format verbatim. json_object is near-universal; json_schema is not - a provider that doesn't implement it returns an error rather than ignoring it. |
| Google Gemini / Vertex | translated | Mapped to Gemini's responseMimeType and responseSchema. Schema keywords Gemini doesn't implement (such as additionalProperties, which OpenAI's strict mode requires) are stripped so a schema written for OpenAI still works. |
| Anthropic | not supported | Claude has no format flag - constrain output with tools instead. The parameter is dropped and reported on x-bold-dropped-params. |
response_format, the response carries x-bold-dropped-params: response_format - so you can detect that the constraint wasn't applied instead of trusting a 200 and failing to parse. This also applies after a failover, which can land on a provider with different support than the one you targeted.Reasoning control
Tune how much a reasoning model thinks with the reasoning object. The gateway translates it into each provider's own parameters, such as Anthropic effort, OpenAI reasoning_effort or a Gemini thinking budget. Models without reasoning ignore it.
| Field | Type | Description |
|---|---|---|
| enabled | boolean | false turns thinking off for a fast, cheap answer. true turns it on for hybrid models that would otherwise skip it. Omit it to keep the model's default. |
| effort | string | minimal, low, medium, high, xhigh or max. Each provider gets the nearest level it supports, so max becomes high on OpenAI. |
| max_tokens | integer | A thinking-token budget, used where the provider offers one: Gemini, Qwen and NVIDIA Nemotron Super. It takes precedence over effort there and is ignored elsewhere. It is separate from the top-level max_tokens. |
| exclude | boolean | Accepted for compatibility. Reasoning text is never returned, so it has no effect. |
curl https://boldrouter.com/v1/chat/completions \
-H "Authorization: Bearer $BOLD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-opus-4.8",
"messages": [{ "role": "user", "content": "Plan a database migration." }],
"reasoning": { "effort": "high" }
}'Use "reasoning": { "enabled": false } to turn thinking off. Some models always think, and there the gateway uses the lightest setting the provider allows instead:
- Lowest effort instead of off: OpenAI reasoning models, Grok mini models, Kimi K3 and GLM-5.3.
- Always on, effort still applies: Claude Fable 5 and Mythos 5. Send
"effort": "low"for the lightest thinking. - No control at all: Kimi K2.7 Code, MiniMax M2.7, Arcee Trinity Large Thinking and gpt-oss.
tool_choice forces a tool call.Fallback chains
Provide a models array to define your own fallback order. If the primary model and all its providers fail, the gateway walks the chain - across providers and models - before giving up. This composes with the automatic provider failover (Routing & failover).
{
"model": "openai/gpt-5.5",
"models": ["anthropic/claude-opus-4.8", "google/gemini-2.5-pro"],
"messages": [{ "role": "user", "content": "..." }]
}Tool calling & multimodal
Pass OpenAI-shaped tools and image content parts; the gateway translates them to each provider's native format and normalizes tool-call deltas and stop reasons back to OpenAI's shape. Vision is supported on models whose catalog entry lists the vision capability.
Two boldrouter extensions ride on the same request: attach documents (PDF, Word, Excel, …) with a file content part - File & document input - and redact PII before it leaves the gateway with anonymize - Prompt anonymization.
