Pricing API
The same dataset that renders every page, as JSON. Free, no key, CC BY 4.0 with attribution to SpendLint and the official source named on each row. Version 1 is stable: fields are only added, never removed or renamed.
Endpoints
GET /api/v1/pricing.json
Whole dataset: providers[], models[], prices[], plus verifiedAt, stale and staleRows[]. Every price row carries amountUsd as a decimal string, unit, dimension, effectiveFrom, optional effectiveTo and supersededBy, verifiedAt and source.url. Rows are never deleted; superseded rows get an end date.
GET /api/v1/pricing/{provider}.json
Same shape filtered to one provider. Valid ids: anthropic openai google azure-openai . Unknown ids return 404 with the valid list.
GET /api/v1/estimate.json
Query parameters: model (required, e.g. anthropic/claude-sonnet-5), rpd requests per day, in, out, cr cache read, cw cache write (5 minute) tokens per request, batch=1. Returns per request, day, month and year USD as decimal strings with the line items and price row ids used. Unknown model or missing price returns 400 with a message; it never returns zero for a missing price.
curl "https://spendlint.dev/api/v1/estimate.json?model=anthropic/claude-sonnet-5&rpd=1000&in=3000&out=600" Semantics
- Amounts are decimal strings, never floats. Parse with a decimal library or as micro-dollars.
- A row is active on date D when
effectiveFrom ≤ Dand (effectiveTois absent or≥ D). Rows with aconditionapply only when the condition holds (for example input tokens above 200,000). stale: truemeans at least one row was verified more than 45 days before the request. Treat those rows as unconfirmed.- Responses cache for one hour and allow cross-origin reads.
Command line
npm install -g spendlint
spendlint check --contract spendlint.yaml --workload workload.json --baseline workload.baseline.json Exit 0 on PASS or WARN, 1 on FAIL, 2 on invalid input. Source and GitHub Action.