# 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.

Source: https://tokentriage.com/docs/build/providers

---
import Callout from '../../../components/Callout.astro';
import NextSteps from '../../../components/NextSteps.astro';
import ProviderStackDiagram from '../../../components/ProviderStackDiagram.astro';

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.

<ProviderStackDiagram />

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](/docs/build/providers-dialects),
[how to authenticate](/docs/build/providers-auth), what URL shape to build, which pricing namespace
to look the model up under, and [which endpoints it serves](/docs/build/providers-endpoints).
[What a provider descriptor carries](/docs/build/providers-descriptors) takes those five facts one
at a time, [how credentials are configured](/docs/build/providers-credentials) covers the
environment-variable half of the upstream, and
[embeddings, rerank, images and audio](/docs/build/providers-specialists) 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.

<Callout type="key">
Pricing binds to the **provider**, not the wire dialect. A `deepseek-r1` request to a DeepSeek
upstream prices under `deepseek/` at $0.55 per million input tokens; the same model string to an
Azure AI Foundry upstream prices under `azure_ai/` at $1.35; the same string to a plain `openai`
upstream is `model_unknown` and produces no figure. All three outcomes come from the same
snapshot, and the third is the one that stops a wrong number.
</Callout>

## 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](/docs/build/providers-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](/docs/build/providers-coverage) |

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](/docs/build/providers-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](/docs/build/providers-azure) |
| Amazon Bedrock | a `region:`, and two or three AWS credential variables | [Bedrock](/docs/build/providers-bedrock) |
| Google Vertex AI | a project, a location, and a service-account key file | [Google](/docs/build/providers-google) |
| self-hosted | nothing, and that is the point — it gets an explicit `$0` | [Self-hosted](/docs/build/providers-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](/docs/build/routing-overview). What happens to a dollar after it is resolved
belongs to [Cost & attribution](/docs/build/cost-analytics): attribution, rollups, exports, and
the verdict each figure carries. Per-tenant credentials, where a customer brings
their own provider key, belong to [Governance](/docs/build/governance-keys). This section stops at
the boundary: reaching the provider, and knowing
[what the request will be looked up as](/docs/build/providers-pricing-keys).

## How to read the rest of it

If you are connecting your first provider, start at
[Connect an OpenAI-compatible provider](/docs/build/providers-connect) and stop there. If the
provider you want is not one of the 95, [adding a provider TokenTriage doesn't
ship](/docs/build/providers-custom) 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](/docs/build/providers-async-jobs) explains the row,
and [reading a settled cost](/docs/build/providers-settlement) 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](/docs/build/providers-dialect-matrix) answers the pair
question directly, [cross-dialect translation](/docs/build/providers-cross-dialect) is the config
that turns it on, [what a translation drops](/docs/build/providers-translation-loss) says what
crossing costs you, and [translated streams](/docs/build/providers-streaming-translation) 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](/docs/build/providers-troubleshooting). If you are deciding
whether to adopt this at all, the page that answers it fastest is
[What isn't covered, and why](/docs/build/providers-coverage), because it names the gaps rather
than the wins.

<NextSteps items={[
  {title: "Connect an OpenAI-compatible provider", href: "/docs/build/providers-connect", description: "You have picked the model; this is the six lines that reach it, and the three checks before you send traffic."},
  {title: "Providers that take a job and answer later", href: "/docs/build/providers-async-jobs", description: "Some of the providers above do not answer in one call, and the row you get back looks broken until you know that."},
  {title: "Which client formats reach which upstreams", href: "/docs/build/providers-dialect-matrix", description: "Before you change any client code, check whether the SDK you already ship reaches the upstream you want."},
  {title: "What isn't covered, and why", href: "/docs/build/providers-coverage", description: "The absences, grouped by what stands in the way, so \"is my provider here?\" is an answer rather than a search."}
]} />
