What isn't covered, and why
The catalog prefixes no descriptor binds, each with the blocker behind it, so you can tell an absence from a misconfiguration.
On this page
The list you want when you are evaluating a gateway is not the one it publishes. Vendors publish the providers they support; you need to know about the one you use, and a positive list makes that a search rather than an answer.
So here is the negative list. Every provider prefix in the vendored price catalog that no descriptor binds, with the reason it is absent, so you can tell in about a minute whether your provider is unsupported, differently named, or already reachable under another descriptor.
The arithmetic, and what each number counts
Two of the numbers on this page are different kinds of claim, and telling them apart matters more than either figure does on its own.
TokenTriage vendors a price table, litellm@2026-07-14#179affb. Its model keys are written
<prefix>/<model>, and the distinct prefixes number 107. That is a statistic about a vendored
price table, not a claim about what TokenTriage can reach. The count of covered prefixes is the
claim: descriptors cover 85 of those 107, and 22 are uncovered. A prefix counts as covered when a
descriptor binds it, 83 by an explicit catalog prefix and 2 by a declared-free descriptor whose
name matches one. That is arithmetic the generator derives, not a test result.
Whether a test gates any given descriptor is a separate axis, and it is published separately: the
matrix names the test behind each gated provider-by-endpoint cell and prints the ones carrying
none as declared (no e2e gate), ten descriptors carrying no gated cell at all. Those tests run
against mocks, not against the providers’ live endpoints.
Covered is not served. oci sits inside the 85 and reaches 19 of its 44 priced keys, and the
generator prints the 25 it cannot reach rather than letting a coverage count imply the rest:
partial reach: "oci" serves 19 of its 44 priced keys; 25 carved out — 19 vendor-excluded 3 surface-not-bound 3 vendor-undocumented
Of those 25, 19 are Cohere models that Oracle’s own package documentation says do not support the
OpenAI-compatible surface this descriptor binds. 3 sit on a sibling Oracle surface the descriptor
does not bind. The last 3 are a defect in the price catalog itself: it prices
oci/openai.gpt-5, -mini and -nano, which Oracle does not document on OCI, while the two
OpenAI models Oracle does document there carry no price at all. The vendored artifact is not
edited to hide that, because a silently corrected copy would disagree with its source.
The 22 uncovered prefixes account for 121 of the catalog’s 2,889 priced model keys, and they partition into five classes:
gap partition: 22 uncovered catalog prefixes, classified in PROVIDER_GAP.md
auth-blocked 1 prefixes, 6 models — blocked on a new credential scheme (Track B)
gigachat 6 models
refused-unverifiable 4 prefixes, 34 models — REFUSED — no primary documentation exists (H24)
darkbloom 2 models
llamagate 16 models
pinstripes 6 models
tensormesh 10 models
refused-bespoke 5 prefixes, 19 models — REFUSED — bespoke/uncertain wire, no verifiable contract
aws_polly 4 models
nlp_cloud 2 models
palm 6 models
sagemaker 6 models
sarvam 1 models
different-wire-deferral 2 prefixes, 3 models — deferred — a different wire on a covered provider family
text-completion-codestral 2 models
text-completion-inception 1 models
alias-or-sub-namespace 10 prefixes, 59 models — not a driver gap — alias / sub-namespace / unwired endpoint
amazon_nova 4 models
bedrock_mantle 10 models
chatgpt 10 models
codestral 2 models
cohere_chat 7 models
fireworks_ai-embedding-models 5 models
meta 1 models
vertex_ai-embedding-models 10 models
vertex_ai-image-models 8 models
vertex_ai-text-models 2 models
total: 22 uncovered prefixes / 121 models (of 107 prefixes / 2889 models in litellm@2026-07-14#179affb)
Both blocks above are output from go run ./tools/matrixgen -dump in the product repo, captured on
2026-08-24 against that pricing artifact. Nothing in them is typed by hand: the counts come from
the descriptor registry, the price file, and the classification markers the gap document carries,
so a clone of the same commit prints the same bytes. TestGapPartitionExact fails when an
uncovered prefix escapes its class, and it is a test you can run.
How the partition is checked, and what the check does not cover
The classification lives in the product’s PROVIDER_GAP.md as one HTML comment marker per
section, <!-- gapclass: auth-blocked --> and so on, over a closed vocabulary of class ids. The
generator reads those markers rather than the headings, so rewording a section’s prose cannot move
a prefix between classes.
TestGapPartitionExact asserts four things: every uncovered prefix appears in some class, none
appears in two, the class sizes sum to the uncovered count, and at least one marker exists. An
unknown class id is a partition problem, and the generator declines to write the file at all
rather than publish a hole. A heading whose advertised count disagrees with the rows beneath it is
a partition problem too.
What the check does not cover: the per-prefix model counts in the gap document’s own tables are hand-typed, and nothing gates them. They agree with the derived figures today. The counts on this page come from the generator output above rather than from those tables.
The five classes, and what separates them
They are not five flavours of not-yet. One is an engineering lever, two are positions we intend to keep, one is a deferral with a published condition, and the largest is not a driver gap at all.
Blocked on a credential the authenticator cannot carry
1 prefix, 6 model rows: gigachat.
Its OAuth2 flow is the straightforward half of the problem. The blocker is a TLS client certificate, which belongs to the shared HTTP transport rather than to the per-provider authenticator, so supporting it means per-upstream transports, which is a subsystem rather than a descriptor.
The lever is per-upstream HTTP transports. The published condition is a second provider needing mutual TLS, at which point those transports become worth building rather than a carve-out for one vendor.
What you can do today. Put GigaChat behind your own certificate-terminating proxy and point a
generic openai_compatible upstream at that proxy. You get routing, governance and a ledger row,
and you hold the certificate. What you do not get is a price binding, because the price binds to
the provider prefix and not to the wire.
Declined because the wire cannot be verified
4 prefixes, 34 model rows.
| Prefix | Model rows | Why it is absent |
|---|---|---|
llamagate |
16 | no primary API documentation found |
tensormesh |
10 | no primary API documentation found |
pinstripes |
6 | no primary API documentation found |
darkbloom |
2 | no primary API documentation found |
The problem is not effort. Without a first-party description of the wire, any mock built to test against is a mock of our own guess, and passing our own guess is not verification. These four stay out, and publishing them with the reason is worth more than quietly omitting them.
The lever is a first-party document. No re-entry condition is published for this class, and that is a position rather than an oversight: closing every other blocker while these four stay out, in public, with the reason, is a statement about the standard rather than about four vendors.
What you can do today. If one of these is your provider and it does publish a wire
description, that document is the thing to send us. Until then openai_compatible will relay to
any OpenAI-shaped endpoint.
Declined because the wire is bespoke, uncertain or gone
5 prefixes, 19 model rows, and 5 different reasons.
| Prefix | Model rows | Why it is absent |
|---|---|---|
sagemaker |
6 | per-endpoint container contract; there is no fixed wire |
palm |
6 | deprecated upstream, Google PaLM retired |
aws_polly |
4 | the AWS-JSON SynthesizeSpeech envelope is not confidently known |
nlp_cloud |
2 | its own non-OpenAI REST API |
sarvam |
1 | one model, OpenAI compatibility unverified |
What you can do today. sarvam and nlp_cloud are the two most likely to work through the
generic escape hatch if their endpoint is OpenAI-shaped: try it, and read the ledger row to see
what arrived. For palm, migrate; Google’s own replacement is covered under vertex_ai and
gemini. For sagemaker there is nothing generic to offer, because there is nothing general to
bind to.
Deferred to a different wire on a family already covered
2 prefixes, 3 model rows: text-completion-codestral (2) and text-completion-inception (1).
The names read like legacy /v1/completions providers. They are not. Both are fill-in-the-middle
endpoints served at POST /v1/fim/completions. For the Mistral one, Mistral’s own reference
documents that path and no POST /v1/completions at all. Binding either would forward to a path
the vendor does not serve.
The lever is either a FimCompletions endpoint kind with its own dated wire notes per vendor,
or a response adapter that translates fill-in-the-middle into a text completion and discloses the
translation on the row. The published condition is that either becomes a card, since neither is
a data change.
What the deferral costs is small, and the gap document says so: the two
text-completion-codestral rows carry no per-token rate in the vendored catalog, so a single
priced row is the whole of what is foregone.
Not a driver gap
10 prefixes, 59 model rows, and the largest slice of the uncovered set is the least interesting one. These are not separate providers. A request for them already routes through an existing driver, or the prefix is an alias or a legacy surface.
| Prefix | Model rows | What it is |
|---|---|---|
bedrock_mantle |
10 | synthetic or forthcoming model ids on Bedrock |
chatgpt |
10 | OpenAI model aliases; use openai/ |
vertex_ai-embedding-models |
10 | Vertex :predict embeddings, a different wire from generateContent |
vertex_ai-image-models |
8 | Vertex Imagen on :predict, likewise a different wire |
cohere_chat |
7 | redundant with cohere/ |
fireworks_ai-embedding-models |
5 | the Fireworks embedding price bucket; the parent is covered |
amazon_nova |
4 | shorthand ids; the Bedrock ids they stand for resolve under bedrock/ |
codestral |
2 | Mistral models; use mistral/ |
vertex_ai-text-models |
2 | Vertex text models; the parent prefix is covered |
meta |
1 | a synthetic model id |
Read that table before concluding your provider is missing, because most of these are reachable today under a name you already have.
The lever for 8 of the 10 is a pricing-bucket descriptor: pure data on an existing
pattern, reusing a driver that already ships, the way bedrock_converse binds its own price bucket
over the Bedrock wire. The published condition is operator demand for a specific bucket’s
prices.
2 of the 10 are not that, and the gap document flags them in its own table: the Vertex embedding and image prefixes sit on a different wire verb, so for those the pure-data description understates the work.
The class that emptied
There used to be a sixth class here, and by model rows it was larger than any of the five above:
7 prefixes carrying 92 priced keys, blocked on submit-and-poll execution, where a provider takes a
job and hands back something to poll instead of answering in the response. replicate, fal_ai, black_forest_labs, runwayml, stability,
assemblyai and soniox were all waiting on one piece of infrastructure.
All 7 now ship. The class stays in the published list with a count of zero rather than being removed, because an empty class says nothing is blocked on this any more, where a deleted one says nothing at all.
Covered is not the same as priced
Closing that class did not turn its 92 priced model keys into dollars, and the two kinds of unpriced
row it left behind are the clearest illustration of what this page is for. That 92 counts catalog
keys under those seven prefixes, not descriptors: replicate 40, stability 23, fal_ai 14,
black_forest_labs 8, runwayml 3, assemblyai 2, soniox 2.
Replicate is a coverage win with no priced dollars. Its prediction wire reports elapsed seconds
and no token count anywhere, while every replicate/ row in the vendored catalog is priced per
token. The unit the price needs is absent from the wire, so all 40 rows settle
UNPRICED(unit_missing) instead of guessing. No catalog edit fixes that, and anyone quoting the 40
in a spend or savings sentence is quoting the wrong number.
Soniox is the mirror image, and it is a data gap. Soniox reports a measured audio duration in
milliseconds, which is what a per-second rate consumes, and the driver settles with that figure as
the provider reported it. Both of its catalog rows carry no rate at all, so the pricing key
resolves and then has no rate units to apply, which is what unit_missing means. One per_second
rate on those two rows would make Soniox priceable with no driver change.
A driver gap and a data gap look identical from a dashboard and cost completely different things to close. Classifying by blocker rather than by vendor is what keeps them apart.
What this list is not saying
It is not a claim about breadth. The price table these counts are measured against belongs to somebody else, and it lists more than this build binds. The claim here is about verification, not size.
It is not a roadmap. Each group above carries a count, a blocker, and where one exists, the condition under which we would look again. A named condition is not a commitment, a date or a place in a queue. Two of the five groups are positions we intend to keep, and one of those two has no condition published at all.
It is not the whole story of an absence. A provider missing from the price catalog entirely does not appear here, because these 22 are prefixes the catalog knows about. If your provider is OpenAI-shaped and absent from the catalog, you can reach it today, and adding a provider covers both routes.