Cloud pricing catalog
InferCost ships with a verified catalog of list prices for OpenAI, Anthropic, and Google models so cloud comparisons work out of the box. The catalog is a single YAML file, overridable per-cluster when you have negotiated enterprise rates.
The catalog file
Canonical location: config/pricing/cloud-pricing.yaml. A byte-identical copy is embedded into the controller binary at build time so the Go code
and the YAML can never silently disagree.
lastVerified: 2026-03-21
sources:
OpenAI: https://developers.openai.com/api/docs/pricing
Anthropic: https://platform.claude.com/docs/en/about-claude/pricing
Google: https://ai.google.dev/gemini-api/docs/pricing
providers:
- provider: OpenAI
models:
- model: gpt-5.4
tier: flagship
inputPerMillion: 2.50
outputPerMillion: 15.00
# ... What list prices do and do not reflect
They are the published public rates on the provider's pricing page. They do not reflect:
- Negotiated enterprise / committed-use agreements
- Batch API discounts (typically 50% off)
- Prompt caching discounts
- Azure OpenAI / Bedrock / Vertex markup or rebate
- Free-tier allocations
For any team with a meaningful cloud contract, the comparison in InferCost is therefore an upper bound on what you would pay going cloud. Override the catalog with your real rates to make the comparison honest both ways.
Overriding with your negotiated rates
In Helm values:
pricing:
override:
enabled: true
inline: |
lastVerified: 2026-07-01
sources:
OpenAI: "Negotiated agreement with OpenAI 2026-Q2"
providers:
- provider: OpenAI
models:
- model: gpt-5.4
inputPerMillion: 1.75 # negotiated 30% off list
outputPerMillion: 10.50 The chart mounts the override as a ConfigMap at /etc/infercost/pricing/cloud-pricing.yaml and passes --pricing-file to the controller. The controller logs which catalog is in use at
startup:
INFO loaded pricing override lastVerified=2026-07-01 providers=1 path=/etc/infercost/pricing/cloud-pricing.yaml A malformed or missing override file causes the controller to fail at startup rather than silently fall back to list prices — if you've configured custom rates, we owe you a loud error when we can't use them.
Refreshing the catalog
The lastVerified field is a contract. When it's older than ~3 months, the catalog
should be refreshed even if nothing visibly changed — "confirmed no change since X" is still
useful. The procedure is one PR, documented in docs/pricing-refresh.md. Pull requests to refresh the default catalog are welcome.
Schema validation
The loader runs Validate() on every file it reads. The three failure modes it
catches, because each of them silently produces wrong cost comparisons:
- Empty or missing
providers - Duplicate
(provider, model)pairs - Negative pricing values
If validation fails on an operator override, the controller logs the specific problem and refuses to start. If validation fails on the embedded catalog, CI catches it before the binary ships.