Providers and dialects
Connect the model providers you already pay for, and know before you send a request which of them TokenTriage can talk to.
On this page
Before you can route anything, cap anything or cost anything, the gateway has to reach the models you already pay for. That is the first configuration decision you make and the one most likely to strand you: a base URL that wants a deployment name in the path, a credential that is four environment variables instead of one, a model that comes back costed at zero because it priced under a namespace you did not expect.
This section is about getting past that. TokenTriage ships 95 built-in provider descriptors, and what counts as support for one is set out below rather than assumed. Four families need more than a base URL and get a page each. When yours is not one of the 95, there are two ways in, and one page that tells you plainly whether either will work.
Three layers, one of which is code
A request reaches a provider through three layers, and it is worth knowing which is which before you write any config, because only the bottom one is a release.
Read it top to bottom. The upstream is yours: a name, a base URL, the descriptor to use, and the name of an environment variable holding the key. The descriptor is data compiled into the binary: which wire to speak, how to authenticate, what URL shape to build, which pricing namespace to look the model up under, and which endpoints it serves. What a provider descriptor carries takes those five facts one at a time, how credentials are configured covers the environment-variable half of the upstream, and embeddings, rerank, images and audio covers the descriptors that serve one surface each rather than chat. The wire dialect driver is Go code, and 15 wire-dialect drivers carry the 95. The generator resolves declared dialect ids from compiled Go packages, including ids whose directory names differ.
Of the 95 built-in provider descriptors TokenTriage ships, 78 point at the openai driver. That
ratio is the whole argument: most of the industry converged on one request shape, so most of what
looks like integration work is a row of data. Adding an OpenAI-compatible provider changes the
middle layer and nothing under it.
What “supported” is allowed to mean here
Every provider count in this section counts built-in descriptors, and the standard behind it is
published beside it rather than assumed. Where a test gates a descriptor’s endpoint, the generated
matrix names that test: it drives a request through the descriptor against a mock upstream shaped
like that provider and asserts the ledger row’s own provider and endpoint stamps. Where no test
gates a cell, the matrix prints declared (no e2e gate) and calls it “not a support claim” rather
than hiding it; ten of the 95 carry no gated cell at all. The verification is against mocks, not
against the providers’ live endpoints.
What the matrix scores is a provider-by-endpoint pair rather than a provider, and it declares 186
such cells at three evidence levels. 99 carry a row-stamp, the strongest: the test asserts the
ledger row’s own provider and endpoint stamps. 10 carry a weaker endpoint-only stamp. 77 print as
declared (no e2e gate). Those three names are used throughout this section, and the
provider reference sets them out beside the table they came from.
Two kinds of number get confused in this market, so they are kept apart here:
| Number | What it counts |
|---|---|
| 95 | built-in provider descriptors; the matrix names the test behind each gated cell and prints the ungated ones, ten descriptors having none |
| 15 | wire-dialect drivers of Go code, the only layer of the three that is a release |
| 107 | provider prefixes in the vendored litellm@2026-07-14#179affb price table: a statistic about a file, not a support claim |
| 2,889 | priced model keys in that same file, keyed <prefix>/<model_key> |
| 85 / 107 | prefixes the descriptors cover, as an identity the generator recomputes: 83 prefix-bound + 2 name-matched declared-free = 85 |
| 22 | prefixes not covered, each one classified by what blocks it |
Two of the 95 are generic shapes rather than vendors: openai_compatible, and local. The first
of those is also the reason the coverage identity has only two addends. openai_compatible binds a
catalog prefix that is not one of the 107, so the generator counts it as covering nothing. It is
the way in for a provider this section does not name, not a row in the arithmetic.
Declared-free is the other term in that identity. 8 of the 95 descriptors assert a price of
zero instead of looking one up, because what they name is a model server you run rather than a
vendor that bills you; their rows carry an explicit $0 with a provenance stamp naming the
descriptor. 2 of those 8 carry a name that is also one of the 107 catalog prefixes, and that is
where the identity’s second addend comes from.
Covered is not served, and the gap between the two is published rather than smoothed over. oci
is counted inside the 85 and reaches 19 of its 44 priced keys; the generator prints the 25 it
cannot, grouped by why. So read 85 as a prefix count with one carve-out attached, and read 107 and
2,889 for what they are: a statistic about a vendored price table, not a claim about what
TokenTriage can reach. The table is LiteLLM’s, and this section counts against it rather than
against a list of our own. Every descriptor behind these figures is listed on the
provider reference, with the wire it rides, its authentication
scheme, its pricing namespace and the endpoints it serves.
The four families that need more than a base URL
Most providers take four lines. Four do not, and they are the four you are most likely to be running in production.
| Family | What it needs beyond a base URL | Page |
|---|---|---|
| Azure OpenAI | a deployment name and an API version in params: |
Azure |
| Amazon Bedrock | a region:, and two or three AWS credential variables |
Bedrock |
| Google Vertex AI | a project, a location, and a service-account key file | |
| self-hosted | nothing, and that is the point — it gets an explicit $0 |
Self-hosted |
Everything else is a base URL, a descriptor name, and an environment variable name: Groq, Together, Fireworks, DeepSeek, Mistral, OpenRouter, xAI, Cerebras and most of the rest of the set.
What this section does not cover
Tiers, cooldown, fallback and the decision to send a request to one upstream rather than another belong to Routing. What happens to a dollar after it is resolved belongs to Cost & attribution: attribution, rollups, exports, and the verdict each figure carries. Per-tenant credentials, where a customer brings their own provider key, belong to Governance. This section stops at the boundary: reaching the provider, and knowing what the request will be looked up as.
How to read the rest of it
If you are connecting your first provider, start at Connect an OpenAI-compatible provider and stop there. If the provider you want is not one of the 95, adding a provider TokenTriage doesn’t ship is the two routes in and what each one costs you.
If the provider you are wiring up answers later rather than in one call, the first ledger row you get back reads as broken until you know why: providers that take a job and answer later explains the row, and reading a settled cost is the month-end procedure that keeps you from counting the same dollar twice.
If you already have an SDK you do not want to change, which client formats reach which upstreams answers the pair question directly, cross-dialect translation is the config that turns it on, what a translation drops says what crossing costs you, and translated streams covers the failure that only happens once frames are already in flight.
If you are debugging a provider that already exists, go to When a provider will not connect. If you are deciding whether to adopt this at all, the page that answers it fastest is What isn’t covered, and why, because it names the gaps rather than the wins.