Models
Call any model directly or let Sansa auto-route for you
Sansa supports two model-selection modes across Chat Completions, Responses, and Anthropic Messages: auto-routing with sansa-auto (Sansa picks the best model for each request) and direct model calls (you choose).
The model field
The model field controls how a Chat Completions or Responses request is dispatched.
Messages difference: POST /v1/messages requires a non-empty model; it does not treat an omitted or null value as auto-routing. Send "sansa-auto" explicitly or use a Claude alias/discovered model ID. See Messages model selection.
| Value | Behavior |
|---|---|
"sansa-auto", null, or omitted | Auto-route. Sansa's router picks the best underlying model for this request. |
Any model ID from the catalog (e.g. "openai/gpt-5.4", "anthropic/claude-sonnet-4.6") | Calls that model directly, with no routing. |
| Unknown model ID | Returns 400 with code invalid_model. |
Pass the model ID exactly as listed on the Models page in your dashboard. IDs follow the provider/model convention (e.g. openai/gpt-5.4, google/gemini-3.1-pro-preview, anthropic/claude-sonnet-4.6).
Auto-routing with sansa-auto
Use sansa-auto when you want Sansa to choose the best model for each request. The router looks at the conversation, tools, reasoning settings, and input types, then picks a model that balances quality and cost. See Smart Routing for how it routes, its reasoning default, and the fields it accepts.
- On Chat Completions and Responses, the response's
modelfield is the model that was used (e.g."openai/gpt-5.4"). Messages echoes the model you sent and reports the routed model insansa.routed_model. - The top-level
sansaobject reports routing metadata (see below). - You are charged at the per-token rate of the selected model.
See the code panel for a complete example.
When to use auto-routing
- You want price and quality handled for you across varied workloads.
- Some requests need deep reasoning, others are simple lookups, and you don't want to build that switch yourself.
- You're migrating an app that hard-codes a model: swap in
"sansa-auto"without touching the rest of your code.
Calling a specific model (gateway)
When you pass a model ID, Sansa calls that model directly. No router runs, and sansa.routed is false.
Use direct model calls when:
- You need a specific model's capabilities or behavior.
- You want deterministic routing (the same model on every request).
- You're A/B testing or benchmarking a specific model against
sansa-auto.
Provider failover
If the model's provider is rate-limited, down, or returns a transient error, Sansa retries the same model on another provider. You get a single response either way.
Unknown model
If the model ID doesn't match any entry in the catalog, the request fails immediately with 400 invalid_model:
{
"error": {
"code": "invalid_model",
"message": "Model 'not-a-real-model' is not a valid model."
}
}The sansa response object
Every completion response includes a top-level sansa object alongside the standard model, choices, and usage fields.
interface SansaCompletionExtension {
// True for sansa-auto / null model requests.
// False for direct model requests.
routed: boolean;
// The model the router selected. Only set when routed is true.
routed_model: string | null;
// Routing latency in milliseconds. Only set when routed is true.
routing_latency_ms: number | null;
}Auto-routed response
{
"usage": {
"prompt_tokens": 24,
"completion_tokens": 412,
"total_tokens": 436,
"cost": 0.00214
},
"sansa": {
"routed": true,
"routed_model": "anthropic/claude-sonnet-4.6",
"routing_latency_ms": 312
}
}Direct model response
{
"usage": {
"prompt_tokens": 12,
"completion_tokens": 28,
"total_tokens": 40,
"cost": 0.00081
},
"sansa": {
"routed": false
}
}Cost by endpoint
- Chat Completions returns billed USD as
usage.cost, including on the final usage-bearing stream chunk. - Responses returns it as
sansa.cost. - Messages has no cost field; see spend in the dashboard.
In streaming responses
See Streaming for where sansa and usage appear in a stream.
Pricing
Pricing is per-model, per-million tokens, billed separately for input and output.
- Auto-routed requests are billed at the rate of the model the router selected.
- Direct model requests are billed at the rate of the model you specified.
- Reasoning tokens are included in
completion_tokens(as in the OpenAI API) and billed at the output rate. - If failover moves a request to another model, it is billed at that model's rate.
Token rates are listed on the Models page.
Errors
| HTTP Status | Code | When |
|---|---|---|
400 | invalid_model | The model value isn't "sansa-auto", null, or a known model ID |
400 | unsupported_parameter | See Completions for the full list |
402 | insufficient_credits | Not enough credits for the request |
503 | provider_unavailable | The model is unavailable on every provider |
See the Errors docs for full error handling guidance.