Auth header: Authorization: Bearer sg_live_... (create a gateway key in the Vault; provider keys stay in your Vault, BYOK)
Client: any OpenAI SDK, or our open-source SDKs (Apache-2.0): sentiogate-python on PyPI (pip install sentiogate-python) and @sentiogate/sdk on npm (npm i @sentiogate/sdk). The SentioGate service itself is proprietary.
model: "auto" picks the cheapest qualifying model; any provider/model id pins one.
Per-request controls: route_preference (cost, quality or latency) and task_class in the body; X-Session-ID keeps a conversation on the same route; X-SentioGate-Cache, X-SentioGate-Tool-Trim, X-SentioGate-Loop-Stop and X-SentioGate-Tool-Guard headers switch those features for one request. Account-wide switches are under Routing policy in the dashboard.
Send model: "auto" and SentioGate ranks the models you enabled in your Vault for each request, by cost, latency and current health. It automatically falls back to another model if one fails: on a rate limit (HTTP 429) or a server error it tries your next key for the same model, then the next ranked model, which can be on another provider. A 429 puts that model on that key into a cooldown shared across requests, honoring the provider's Retry-After, so later requests skip it.
Send a provider/model id to pin one model. A pinned model only gets key failover; it never switches to a different model. OpenRouter model ids keep their own slash, for example openrouter/anthropic/claude-sonnet-4. GET /v1/models lists the ids you can route to.
Authentication and your provider keys (BYOK)
Every request carries a SentioGate gateway key (sg_live_...) as Authorization: Bearer sg_live_.... Create one in the dashboard.
The Anthropic-compatible /v1/messages endpoint also accepts the key as x-api-key, which is what Anthropic SDKs and Claude Code send.
Your provider keys (for example OpenAI, Anthropic, Gemini, Groq, Mistral, DeepSeek, xAI or OpenRouter) go in the Vault, encrypted at rest. Providers bill your own accounts directly, with 0% token markup.
You can store up to 5 keys per provider, in priority order, with optional per-key spend and balance limits that pause a key.
model: "auto" only routes to models you enabled in the Vault.
Endpoints
POST /v1/chat/completions
OpenAI-compatible Chat Completions. With stream: true the Server-Sent Events stream is passed through and router metadata arrives in the X-SentioGate-Router response header.
GET /v1/models
Lists the model ids you can route to.
POST /v1/messages
Anthropic Messages API, for Claude Code and Anthropic SDKs. Claude models need your own Anthropic or OpenRouter key.
POST /v1/messages/count_tokens
Counts input tokens for a Messages request.
Free community pool (no provider keys yet)
With a gateway key and no provider keys in your Vault, model: "auto" is answered by the free community pool: 600 requests per 5 hours per user during the beta, with no credit card. It is meant for testing your integration. Other model ids need your own provider key. Once you add keys, the same model: "auto" call routes across them with no code change.
Errors and retries
Errors use the OpenAI error shape: {"error": {"message", "type", "code"}}. Check error.code:
401 invalid_api_key
Missing or invalid gateway key.
403 no_enabled_models
auto found no enabled models in your Vault. Enable at least one model.
403 community_model_only
No provider keys yet, and the request asked for a specific model. Send auto, or add your own key.
403 community_pool_disabled_with_byok
The request asked for the community pool while provider keys are saved. Send auto or a provider/model id.
429 upstream_rate_limited
Your providers rate-limited every model SentioGate tried. Wait for Retry-After, or add another key or provider.
429 community_pool_exhausted
You used your community pool requests for this window. Retry-After is the time until it frees up.
503 community_busy
The shared community pool is briefly busy. Retry after the short Retry-After.
Wait at least Retry-After before retrying, and retry in one layer only: if you use the OpenAI SDK's built-in retries, leave SentioGate SDK retries off, or the other way round.
Which model answered: router metadata
Non-streaming responses include a router object next to the usual OpenAI fields, with the policy that ran, the reason a model was picked and any fallback attempts. Log it to see which provider and model actually answered. The full request and response schemas are in the endpoint reference below.
Endpoint reference
Inference
POST/chat/completionsCreate a chat completion (OpenAI-compatible)
With `stream: true` the upstream Server-Sent Events stream is passed through unchanged and router metadata is returned in the `X-SentioGate-Router` response header (JSON). Non-streaming responses carry the same metadata in the `router` field.
Parameters
X-Session-IDheader
string
Conversation or agent-session id (max 256 chars). Optional: keeps the requests of one session together, so `model: "auto"` stays consistent across tool turns and provider prompt caching works better.
X-SentioGate-Prompt-Cacheheader
"off"
Send `off` to stop SentioGate adding a provider prompt-cache breakpoint. Client cache_control fields are always forwarded.
X-SentioGate-Cascadeheader
"on" | "off"
Cascade (opt-in, non-streaming, `model: "auto"`): `on` first tries a cheaper model from your vault and, if its answer does not pass SentioGate's quality checks, retries once with the normal pick. Both attempts are billed by your provider. `off` turns it off for this request. The outcome is reported in `router.cascade`.
X-SentioGate-Length-Capheader
"on" | "off"
Send `on` to enable the answer-length cap for this request (off by default), or `off` to disable it.
X-SentioGate-Cacheheader
"off" | "bypass" | "force"
Send `off` (or `bypass`) to skip the response cache, or `force` to cache this request at any temperature (still never for streaming, tools or n>1). Responses carry `X-SentioGate-Cache` (`exact`, `semantic`, `miss` or `skip-<reason>`) and, on a hit, `X-SentioGate-Cache-Saved-USD`.
X-SentioGate-Tool-Trimheader
"on" | "off"
Tool-output trimming (on by default for `model: "auto"` and your own keys): shortens large tool results from earlier agent steps. System, user and assistant messages and the newest tool results are never changed. Send `off` to opt out for this request, or `on` to apply it when your account setting is off. Savings are reported in `router.tool_trim`.
X-SentioGate-Loop-Stopheader
"on" | "off"
Runaway-loop stop (on by default). When an agent looks stuck repeating the same steps, the request is flagged in the `X-SentioGate-Loop` response header and answered with 400 `loop_detected` instead of calling a model. Send `off` to only flag it (overrides the account setting); `on` forces the stop.
X-SentioGate-Tool-Guardheader
"flag" | "off"
Dangerous tool-call flag (on by default). When the model asks to run a tool call that looks dangerous, such as deleting the root or home directory, piping a download into a shell, sending credential files or secrets out, or force-pushing to main, the response is flagged in the `X-SentioGate-Guard` response header and in `router.guard`. On streams the flag arrives as an SSE comment line starting with `: x-sentiogate-guard` before the end of the stream. Flag only: the answer is never changed or blocked. Send `off` to skip the check for this request (overrides the account setting).
X-SentioGate-Allow-Queueheader
"on" | "off"
Advanced, for background jobs only. On a non-streaming request served by the free community pool, `on` lets a busy pool answer 202 Accepted with a poll link (`Location: /v1/batch/poll/{jobId}`) instead of a busy error. Requests on your own provider keys are always answered directly.
Request body ChatCompletionRequest
model
string
`auto`, `provider/model` (e.g. `openai/gpt-4o-mini`) or a bare model id.
messagesrequired
Message[]fields
rolerequired
"system" | "user" | "assistant" | "tool"
contentrequired
string | object[]
name
string
stream
boolean
temperature
number
Sent upstream only when set; unset uses the provider default.
Optional hint for `model: "auto"` that overrides the automatic task detection.
route_preference
"cost" | "quality" | "latency"
`cost` (default): lowest price among suitable models. `quality`: prefer more capable models. `latency`: prefer faster models.
session_id
string
Same as header X-Session-ID.
cache_control
object
Forwarded untouched to the provider. Block-level cache_control inside messages is also forwarded untouched.
prompt_cache_key
string
Forwarded (OpenAI-style cache routing key).
prompt_cache
boolean
false stops SentioGate auto-inserting a prompt-cache breakpoint.
cascade
boolean
Same as header X-SentioGate-Cascade.
length_cap
boolean
true enables the answer-length cap for this request (off by default; same as header `X-SentioGate-Length-Cap: on`). It applies only when you set no max_tokens / max_completion_tokens and the request is not streaming; an answer cut by the cap is retried once without it.
cache
boolean
false skips the response cache (same as header `X-SentioGate-Cache: off`); true opts in at any temperature (same as `force`). By default only deterministic requests are cached (a low temperature, or a single-turn factual question with temperature unset).
tool_trim
boolean
false turns tool-output trimming off for this request (same as header `X-SentioGate-Tool-Trim: off`).
compress
"auto" | "lossless" | "on" | "off"
Context compression. `auto` (default): lossless clean-up only, plus summarizing older turns when a long session nears the model's context limit. System prompts, code blocks and tool-call pairs are never changed, and provider prompt caching keeps working. `lossless`: never summarize. `on`: summarize older turns more readily. `off`: send messages unchanged. Header `X-SentioGate-Compress` is equivalent. Savings are reported in `router.compression`.
Optional hint for `model: "auto"` that overrides the automatic task detection.
min_tier
integer
model_tier
integernull
estimated_prompt_tokens
integer
estimated_output_tokens
integer
estimated_cost_usd
numbernull
pricing_source
string
reason
string
candidates
integer
attempts
string[]
`provider/model:status` per upstream attempt.
route_preference
"cost" | "quality" | "latency"
`cost` (default): lowest price among suitable models. `quality`: prefer more capable models. `latency`: prefer faster models.
measured_latency_ms
numbernull
Recently measured latency of the chosen model, if known.
prompt_cache
object
Provider prompt-cache usage for this response and the estimated saving.
fields
cached_tokens
integer
cache_write_tokens
integer
saved_usd
numbernull
saved_source
stringnull
auto
objectnull
agent
object
Present on `model: "auto"` requests that carry tools.
fields
tools
boolean
tool_rounds
integer
cost_source
string
How estimated_cost_usd was computed (for example from the provider's published prices, or `unknown_price`).
reasoning_retry
object
Present when a reasoning model returned an empty answer and the request was retried automatically. Both attempts are billed.
cascade
object
Present when cascade was requested.
fields
attempted
boolean
escalated
boolean
reason
string
`passed`, or why the cheaper answer was not used.
first_model
string
first_cost_usd
number
first_latency_ms
integer
length_cap
object
Answer-length cap: whether it applied, the token limit, and whether a truncated answer was retried uncapped.
fields
cap_applied
boolean
cap_tokens
integer
cap_retry
boolean
cap_skipped
"not_enabled" | "client_limit" | "streaming"
cache
objectfields
hit
boolean
layer
"exact" | "semantic"
cost_usd
number
saved_usd
number
skipped
string
tool_trim
object
Present when tool-output trimming changed this request.
fields
trimmed
integer
chars_saved
integer
tokens_saved_est
integer
loop
object
Present when the agent looks stuck in a loop.
fields
suspected
boolean
count
integer
guard
object
Present when the answer contains tool calls and the dangerous tool-call flag is on. Flag only: the answer is not changed.
fields
mode
"flag"
inspected
integer
Tool calls checked.
flagged
integer
Tool calls that look dangerous.
rules
string[]
Ids of the matched rules, for example `rm-root-or-home`, `pipe-to-shell`, `secret-file-exfil`, `force-push-main`, `secret-in-outbound-args`.
compression
objectfields
applied
boolean
original_tokens
integer
compressed_tokens
integer
saved_tokens
integer
saved_pct
number
mode
string
lossy
boolean
summary_cost_usd
number
400
Invalid request body. Also when the agent looks stuck repeating the same steps and runaway-loop stop is on, the default (`loop_detected`). Change the approach or input and send again; retrying the same request gives the same answer.Error
POST/messagesCreate a message (Anthropic Messages API)
Anthropic-compatible endpoint for Claude Code and Anthropic SDKs: set `ANTHROPIC_BASE_URL=https://api.sentiogate.dev` and `ANTHROPIC_API_KEY` to your `sg_live_...` key (sent as `x-api-key` or `Authorization: Bearer`). `?beta=true` is accepted.
With your own Anthropic key in the Vault, `claude-*` models are sent natively to Anthropic, so the request (thinking, tools, cache_control, documents) and the response or SSE stream are passed through as Anthropic sent them.
Any other model (`auto`, `provider/model`, a bare id) is translated to an OpenAI-compatible chat completion on your vault keys and the answer is translated back into Anthropic's message shape and SSE event order (`message_start`, `content_block_*`, `message_delta`, `message_stop`).
Without vault keys, only `auto` (or `sentiogate-community`) is served, on the free community models; other ids return 403 `permission_error`. For Claude Code set `ANTHROPIC_MODEL=auto` and `ANTHROPIC_SMALL_FAST_MODEL=auto` (and `ANTHROPIC_DEFAULT_HAIKU_MODEL=auto`). Claude models need your own Anthropic or OpenRouter key.
A 429 carries the upstream `Retry-After` when the provider sent one. Router metadata is returned in the `X-SentioGate-Router` header.
Parameters
anthropic-versionheader
string
Anthropic API version (default `2023-06-01`). Forwarded on native Anthropic calls.
anthropic-betaheader
string
Anthropic beta flags. Forwarded on native Anthropic calls.
X-SentioGate-Tool-Trimheader
"on" | "off"
Tool-output trimming (on by default for `model: "auto"` and your own keys): shortens large tool results from earlier agent steps. System, user and assistant messages and the newest tool results are never changed. Send `off` to opt out for this request, or `on` to apply it when your account setting is off. Savings are reported in `router.tool_trim`.
X-SentioGate-Loop-Stopheader
"on" | "off"
Runaway-loop stop (on by default). When an agent looks stuck repeating the same steps, the request is flagged in the `X-SentioGate-Loop` response header and answered with 400 `loop_detected` instead of calling a model. Send `off` to only flag it (overrides the account setting); `on` forces the stop.
X-SentioGate-Tool-Guardheader
"flag" | "off"
Dangerous tool-call flag (on by default). When the model asks to run a tool call that looks dangerous, such as deleting the root or home directory, piping a download into a shell, sending credential files or secrets out, or force-pushing to main, the response is flagged in the `X-SentioGate-Guard` response header and in `router.guard`. On streams the flag arrives as an SSE comment line starting with `: x-sentiogate-guard` before the end of the stream. Flag only: the answer is never changed or blocked. Send `off` to skip the check for this request (overrides the account setting).
Request body MessagesRequest
modelrequired
string
`claude-*` (native with your Anthropic key; via OpenRouter as `anthropic/<id>` otherwise), `auto`, `sentiogate-community`, or `provider/model`.
max_tokensrequired
integer
messagesrequired
object[]fields
rolerequired
"user" | "assistant"
contentrequired
string | object[]
system
string | object[]
stream
boolean
temperature
number
top_p
number
top_k
integer
stop_sequences
string[]
tools
object[]
Custom tools are supported on every route; Anthropic server tools only on the native route.
tool_choice
object
thinking
object
metadata
object
Responses
200
Message. `text/event-stream` when `stream: true`.MessagesResponse
Invalid request (`invalid_request_error`). Also when the agent looks stuck repeating the same steps and runaway-loop stop is on, the default (`invalid_request_error`). Change the approach or input and send again; retrying the same request gives the same answer.AnthropicError
For `claude-*` models with your own Anthropic key in the Vault, Anthropic counts the tokens. Otherwise SentioGate returns an estimate. The `X-SentioGate-Token-Count` response header says which (`anthropic` or `estimate`).
Parameters
anthropic-versionheader
string
Anthropic API version (default `2023-06-01`). Forwarded on native Anthropic calls.
anthropic-betaheader
string
Anthropic beta flags. Forwarded on native Anthropic calls.
Request body MessagesRequest
modelrequired
string
`claude-*` (native with your Anthropic key; via OpenRouter as `anthropic/<id>` otherwise), `auto`, `sentiogate-community`, or `provider/model`.
max_tokensrequired
integer
messagesrequired
object[]fields
rolerequired
"user" | "assistant"
contentrequired
string | object[]
system
string | object[]
stream
boolean
temperature
number
top_p
number
top_k
integer
stop_sequences
string[]
tools
object[]
Custom tools are supported on every route; Anthropic server tools only on the native route.
GET/pricingModel list prices used for routing and cost estimatespublic
Responses
200
Pricing snapshotobjectobject
GET/pricing/modelsPer-model list prices (USD per token), context length, tool support and capability tierpublic
Responses
200
Model price catalogobject
source
string
fetched_at
stringnull
count
integer
models
object
POST/waitlistGet an email when a coming-soon paid plan launches ("Notify me" on /pricing)public
No account needed; when signed in, the account is linked to the sign-up. Stores only the email, the plan and the time. Signing up twice for the same plan is fine and returns the same answer. Nothing is emailed until the plan launches. Rate limited per IP.
Request body
emailrequired
string
planrequired
"pro" | "team"
Responses
200
On the listobject
status
"subscribed"
plan
"pro" | "team"
message
string
400
Invalid email or planDetail
detail
string
429
Too many sign-ups from this address; see Retry-AfterError
Opt-in export of a trace per chat request to your own Langfuse project. Off by default. Fields you leave out keep their saved value; `secret_key` is write-only and stored encrypted. Enabling needs both keys. Prompts and answers are only exported when `include_content` is true; otherwise traces carry metadata only (model, provider, token usage, cost, latency, status).
Request body LangfuseSettingsUpdate
enabled
boolean
include_content
boolean
Also export prompts and answers. Default false (metadata only).
host
string
HTTPS Langfuse host (self-hosted allowed; private addresses are rejected).
public_key
string
Starts with `pk-lf-`.
secret_key
string
Starts with `sk-lf-`. Write-only: stored encrypted and never returned.
Responses
200
Saved settingsLangfuseSettings
configured
boolean
enabled
boolean
include_content
boolean
host
string
Langfuse host, for example `https://cloud.langfuse.com` or `https://us.cloud.langfuse.com`.
public_key
stringnull
Masked public key.
has_secret_key
boolean
updated_at
integernull
Unix time in milliseconds.
400
Invalid JSON, host or key, or enabling without both keysDetail
detail
string
401
Not authenticatedDetail
detail
string
503
Temporarily unavailableDetail
detail
string
DELETE/integrations/langfuseTurn off the Langfuse export and delete the saved keys
Responses
200
Settings after deletion (`configured: false`)LangfuseSettings
configured
boolean
enabled
boolean
include_content
boolean
host
string
Langfuse host, for example `https://cloud.langfuse.com` or `https://us.cloud.langfuse.com`.
public_key
stringnull
Masked public key.
has_secret_key
boolean
updated_at
integernull
Unix time in milliseconds.
401
Not authenticatedDetail
detail
string
503
Temporarily unavailableDetail
detail
string
POST/integrations/langfuse/testCheck the saved Langfuse keys against your Langfuse host
Responses
200
Result. `ok: false` with a `detail` when the keys are missing, rejected or the host is unreachable; `status` is the HTTP status Langfuse answered (0 when unreachable).object
okrequired
boolean
status
integer
detail
string
401
Not authenticatedDetail
detail
string
429
Tested too often; `Retry-After` says when to try again.object
ok
boolean
detail
string
503
Temporarily unavailableDetail
detail
string
Discover
POST/workload/analyzeEstimate savings from an uploaded log export (JSON, JSONL or CSV, max 5 MB). Nothing is stored.public
Request body
raw
string
File contents
records
object[]
Responses
200
Estimated reportobjectobject
400
Empty or unparseable inputDetail
detail
string
413
Upload too largeDetail
detail
string
Batch
POST/batch/enqueueSubmit an asynchronous task to the free community pool
Request body
item_text
string
messages
Message[]fields
rolerequired
"system" | "user" | "assistant" | "tool"
contentrequired
string | object[]
name
string
model
string
Responses
202
Queued task with poll_urlobject
job_id
string
status
string
poll_url
string
400
Invalid payloadDetail
detail
string
401
Sign-in or API key requiredDetail
detail
string
403
The free community pool is not available for this account (for example when you have provider keys in the Vault)Detail
detail
string
413
Item too largeDetail
detail
string
429
Personal allowance (600 requests per 5 hours) used up, too many pending items, or rate limitedDetail
detail
string
GET/batch/poll/{jobId}Check status and retrieve results of an enqueued batch task
Parameters
jobIdpathrequired
string
Responses
200
Job status and completed model output (owner only)object