Docs

An OpenAI-compatible endpoint. If your tool takes a base URL and a key, it already works: this is the exact configuration, not a simplified version of it.

Endpoint

Base URL & auth

One base URL, bearer auth with your API key. The endpoint speaks the OpenAI chat-completions and completions APIs.

base url
https://api.tium.ai/v1

Authorization: Bearer sk-tium-...

Get a key from your dashboard. Keys are shown once at creation; store them in an environment variable, never in source.

Requests

Making a request

The same call three ways. Any slug from /models drops into the same field.

curl https://api.tium.ai/v1/chat/completions \
  -H "Authorization: Bearer $TIUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-5.3-flash",
    "messages": [{"role": "user", "content": "Say hello."}]
  }'

Configuring a tool rather than writing code? Every one of these has a setup page with its config, where the key belongs, and what that tool gets wrong.

All 15 setup guides, and anything else that takes an OpenAI-compatible base URL.

Headers

What every response tells you

Each response carries what it cost, what remains, and your limits. You never have to take a number on trust.

X-Tium-Request-IdCorrelation id for support. Present on every response, including errors.
X-Tium-Tokens-In / -Cached / -OutThe token counts this request was billed on (non-streamed responses).
X-Tium-Weighted-TokensWeighted tokens charged: the token counts times the published weights and model multiplier.
X-Tium-Model-MultiplierThe multiplier applied, captured at request time. What you see is what you were charged.
X-Tium-Output-WeightThe output-token weight used for this model, captured the same way.
X-Tium-Balance-RemainingWeighted tokens left (allotment + credits) at the start of the request.
X-Tium-Concurrency-Limit / -RemainingYour tier's concurrency limit and how many slots were free.

On streamed responses the X-Tium-Tokens-* and X-Tium-Weighted-Tokens headers are absent, because the counts do not exist yet when headers are sent. Instead we set stream_options.include_usage on every streamed request, so the stream ends with a standard OpenAI usage chunk carrying the token counts. We set it whether or not you asked for it; that is how the request gets billed correctly. Identity, balance and concurrency headers are sent up front as usual.

Errors

Error codes, and which to retry

The distinction that matters for agents: 402 is a wall (out of balance) and must not be retried; 429 is backpressure (too many at once) and should be retried after a short wait.

HTTPerror.typeMeaning
400invalid_request_bodyThe JSON body was malformed. Fix the request; do not retry as-is.
400too_many_candidates'n' (or 'best_of') exceeds the per-request cap. The body carries the limit.
401missing_api_keyNo Authorization header. Send 'Authorization: Bearer sk-tium-...'.
401malformed_authorizationThe Authorization header is not of the form 'Bearer <api-key>'.
401invalid_api_key / revoked_api_keyKey is wrong or has been revoked.
402insufficient_balanceAllotment and credits are exhausted. Top up. Agents must NOT retry a 402.
402key_spend_limit_reachedThis key hit its per-key spend limit. Raise the limit or use another key.
403model_not_permittedThe model exists; this key may not use it. Body carries available_models.
404model_not_foundUnknown model slug. Body carries available_models; fall back to one of those.
429concurrency_limitToo many requests at once for your tier. Retry after a short wait; carries Retry-After.
429daily_burst_cap_reachedDaily burst cap reached (abuse guard). Resets 00:00 UTC.
502backend_unavailableThe inference backend is unreachable. Transient; safe to retry.
502backend_error / bad_gatewayThe backend answered with an error or a non-JSON body. Not billed for tokens.
503model_unavailableThis model's provider is failing and was withdrawn. Retry-After carries the cooldown.
503registry_unavailableServer-side configuration problem, not your request. Retryable.

Errors return an OpenAI-shaped body under error. Note which field is which: type is the slug above, code is the HTTP status as an integer.

typeThe error slug: the value in the table above. Switch on this.
codeThe HTTP status, as an integer. Not a slug.
messageHuman-readable, safe to surface to a developer.
request_idMatches X-Tium-Request-Id. The one field support needs.
retryableBoolean. Authoritative: prefer it over inferring from the status.
retry_after_msOn 429s, the same interval as the Retry-After header, in milliseconds.
allotment_reset_atOn 402s, when the monthly allotment next refills.
top_up_urlOn 402s, where to add credits.
available_modelsOn 403 and 404, the slugs this key can actually reach.
limitOn 429 concurrency_limit and 400 too_many_candidates, the bound that was hit.

Fields beyond the first four appear only where they apply. The one worth wiring up is retryable: it is set deliberately per error rather than derived, so an agent that honours it gets the 402-vs-429 distinction right without encoding a table of statuses.

Limits

What the gateway changes about your request

Three request-shaping rules. The first one is silent, which is why it leads.

max_tokens is clamped to what you can afford

Before dispatch we reserve the prompt’s cost, then cap output at what the remaining balance buys at this model’s rate. Your effective ceiling is the lowest of the max_tokens you asked for, the model’s published output ceiling, and that affordable number. If the affordable number is lower, the response is truncated, not refused: you get a normal completion with finish_reason: "length". Watch X-Tium-Balance-Remaining if short completions start appearing. If the balance cannot cover even the prompt, the request is refused with a 402 and billed nothing.

n and best_of are capped

Parallel completions multiply generation, so they are settled at the door: over the cap you get a 400 too_many_candidates with the exact limit in limit. Send the requests separately instead.

stream_options.include_usage is forced on

On streamed requests, so the trailing usage chunk exists and the request can be billed on measured tokens rather than an estimate. Any other stream_options you send are preserved.

Everything else in the request body is passed through to the backend unchanged, including tools, temperature and stream. Both /v1/chat/completions and /v1/completions are served.

Discovery

GET /v1/models

Authenticated, and served from our registry rather than proxied from an upstream catalog: it lists what we can actually route and price.

list models
curl https://api.tium.ai/v1/models \
  -H "Authorization: Bearer $TIUM_API_KEY"

Each entry is an OpenAI model object with our own fields alongside it, so a client can price and size a request before sending it:

idThe published slug: what you send as 'model'.
context_windowContext tokens served for this model.
tium_max_output_tokensThe output ceiling we enforce, before the affordability clamp.
tium_multiplierThis model's price multiplier, the same number the response header reports.
tium_output_weightThe output-token weight used in the weighted-token formula.
tium_deprecatedPresent and true only while a model is on its way out.
tium_retires_atPresent alongside it: when the slug stops being served.

The two deprecation fields are absent rather than null when a model is not deprecated. A null on every model trains clients to ignore them. When they do appear, the model is still served and still billed; it is telling you to migrate before the day it starts returning 404.

The same catalog, with every model’s context, output ceiling, multiplier and published weights, is on /models.

Further

The rest of the documentation

Three things that are their own pages because each answers a question somebody arrives with, rather than one they run into halfway down this one.

  • What we measured

    Behaviour we found by sending a request rather than reading a datasheet: thinking that cannot be disabled, effort levels that do nothing, a forced tool call that is refused. Each names its probe and the date it ran.

  • Prompt caching

    The largest lever on what an agent costs, with the numbers off a real session rather than a benchmark we designed.

  • What a weighted token is

    The whole formula, why the unit exists, and what the trial buys, computed from the catalog rather than typed.