Skip to main content
If you work at a model or inference provider, this is the highest-value thing you can do for the developers costing out your API. Right now your prices reach this catalog because a person reads your pricing page. That is slow, it breaks whenever you restyle the page, and when it breaks the wrong number gets published under your name. Publish one endpoint instead and that stops happening. We poll it every day, so the day a rate moves we know, and the catalog is corrected from your own numbers rather than from a guess at your page.
This is not a new standard. OpenRouter and LiteLLM already publish per-token rates in this shape, and this project already pulls from both. The only addition is the two meters that voice needs: characters of text and seconds of audio.

What we need

A single HTTPS GET that returns your current rates as JSON.
That is a complete, valid response.

The two requirements that make it worth doing

Generate it from whatever your billing system treats as the source of truth. This is the whole point. An endpoint a human edits by hand is a pricing page with extra steps: it will drift, and because we poll it, that drift becomes visible rather than staying quietly wrong. If the number you serve is the number you bill, the endpoint is correct permanently and you never think about it again. Quote every rate per one base unit: one character, one second, one token, one request. Never per thousand or per million. This is where public pricing data goes wrong most often, because $30 is a plausible price per million characters and a catastrophic one per thousand. If the number is small and the unit is singular, there is nothing to misread. Publish amounts as strings for the same reason: 0.0000003 as a JSON number does not survive a round trip through every language’s float parser.

Serving it

It does not need to be fast or highly available. We poll once a day and treat a timeout as a transient failure, never as a price change.

Fields

Top level

Per model

Per rate

A rate with no plan, from_quantity, or voice_class is your headline rate. Publish at least one of those per meter, or there is nothing to compare against.

Supported meter and unit pairs

Every combination below maps to exactly one field in this catalog. Anything not listed is rejected rather than guessed at, because a wrong unit and a wrong price look identical once stored.

Get the model id right

This is the field most often wrong and the only one that makes an endpoint machine-usable. id must be the literal string a caller passes to your API. Not the marketing name, not the docs slug, not the pricing-page row label.
Every downstream tool has a fuzzy matching layer purely because providers publish the second form. Getting this right deletes that layer.

Check it before you ship it

This validates the response, converts every rate, and diffs it against what this catalog currently publishes about you. It works on a local path too, so you can check what your build produces before it goes live:
It exits non-zero when something drifts or cannot be mapped, so it doubles as a check in your CI: fail your build the day your published rates stop matching what you actually charge. Call the module directly there to avoid make’s own error line, which signals findings rather than a crash:

Register it

Open an issue with the URL, or send a pull request adding one line to your provider file:
From then on a scheduled job polls your endpoint daily and flags any rate that has moved away from the catalog.
Polling never rewrites a price on its own. A moved rate alerts a maintainer, who confirms it and updates the entry by hand. No job in this project is allowed to mark a price as verified, which is what makes the dates on every page mean something. How Fresh? explains the rule.
Anything that does not fit the shape above, open an issue and we will work it out.