GET /v1/prices/history returns the reviewed price history: every published price, old rates included, as it stood at an instant you choose. Call it instead of keeping a copy of the prices; pin the instant to make a computation reproducible.
Query parameters
Response
200 OK
Price rows
A price line is one provider, source, resource, dimension, unit, currency and tier. Its current price at
asOf is its row with the newest recordedAt; the older rows are its history.
New fields may be added to the response. Ignore fields you do not recognize.
Pinning with asOf
A row is in the answer atasOf when it was published at that instant. A price published on day 1 and withdrawn on day 2 is in the answer at a day-1 asOf and not at a day-2 one. Nothing that happens later changes the answer at an earlier asOf, so the same asOf always returns the same rows, and approvalStatus is the status at asOf, not today’s.
asOf cannot be later than 15 minutes ago: prices land shortly after the instant they carry, and a read closer to now could miss rows that a later read at the same instant would see. A later value is 400 as_of_too_recent.
Store the response’s asOf beside anything you compute from it; asking again with it reproduces the input exactly. With alias= that holds while alias.revision is unchanged (Alias groups).
Paging
Rows are ordered bycontentHash. While nextCursor is not null, request the next page with cursor and limit only. Ask only for the providers you need: one large provider can be tens of thousands of rows.
- What a cursor pins:
asOf,providers, thealiasgroup at the revision the first page read, and the position. Every page of one walk reads the sameasOf. SendingasOf,providersoraliasbeside a cursor is400 invalid_query(error.fieldiscursor). - What it does not pin:
limit. Each request uses thelimitsent with it, or 5,000 when none is sent. Send the samelimiton every page. - Lifetime: a cursor does not expire. Its
asOfis in the past, so the rows behind it never change and a walk can continue later. A cursor withaliasstops working once the group changes. - After
409 alias_changed: the group changed between pages (its members or its name, or it was deleted), so the pages already read may belong to the old group. Discard them and start again from the first page, without a cursor. To read the same instant, send the first page’sasOfback with the samealiasandproviders; withoutasOf, the new walk reads a newer instant. - After
429 rate_limited: the endpoint has its own rate limit. Waitretry-afterseconds and send the same request again; the cursor stays valid.
Node.js 18 or later (built-in fetch)
Python
Alias groups
alias= narrows the answer to one alias group: the same resource at every provider that sells it, each under its own name. The rows are the ordinary rows of the group’s members; nothing is merged or converted. The answer adds the group:
alias.idis the group’s stable id;alias.nameis its display name, which can change.alias=accepts either.membersis the whole group. Rows are served for the members whose provider is inproviders; withoutproviders, those are the active USD-priced providers that sell it.- An unknown group is
404 alias_not_found. - The rows are pinned to
asOf; the group is not. Membership is always the group as published when you read it: there is no parameter to ask for an earlier revision, so the sameasOfcan return other rows after the group changes. Storealias.revisionbesideasOfto tell whether the group changed since you last read it. A different revision means the group was saved again: its members may have changed (thealias.member_addedandalias.member_removedwebhook events say how), or only its name, or nothing visible. Comparemembersto know. - If the group changes while you page through it (any new revision, or it is deleted), the next page is
409 alias_changed: start again from the first page (Paging). - A member is an exact resource name: a renamed resource’s earlier rows are included only if the group lists the old name too.
Prices that are not money
price is in currency, which is not always USD. snowflake prices in two steps: what a service consumes in credits (unit: credit_per_token, currency: SNOWFLAKE_AI_CREDIT or SNOWFLAKE_PLATFORM_CREDIT) and what a credit costs (unit: usd_per_credit, currency: USD, per cloud, region and edition in pricingTier). The cost in USD is the consumption rate times the usd_per_credit price of the same credit type.
These rows are served only when you name the provider (providers=snowflake), so code that sums price as money never receives them by default.
Renamed resources
When a provider renames a resource, rows under the old name carryrenamedTo: the name the resource is listed under at asOf. Join on source and renamedTo to read one history across the rename. Rows of a resource that was never renamed have no renamedTo.
Errors
GET /v1/providers
The provider directory: the slugs to use inproviders and in webhooks.
status is active, or pending while a provider is being added (a webhook can already subscribe to it). activatedAt is null for providers older than the directory. freshness is fresh, stale or unknown.
GET /v1/comparison/aliases
The published alias groups.200 OK
groups has an id, a resource, a revision, updatedAt and its members (provider, resource). The same group has other field names elsewhere:
alias= and a webhook’s alias groups take the id or the name; a webhook stores the id. A group whose members are all no longer listed (their provider or sources were retired) is listed with no members and "retired": true. version is the version of the whole catalog: it goes up with every change to any group, deletions included, so it can be higher than every listed group’s revision. unpriced lists the members whose resource has not been seen priced for a week. resources lists every resource the catalog knows, with comparisonResource: the name of its group or, when it is in none, its canonical id (else its own name). canReview is always false for an API key.
GET /v1/catalog
GET /v1/catalog?provider=openai lists what you can filter a webhook on for one provider: resources (each with resource, canonicalResource and dimensions) and docs (each with the document slug doc and its url).
200 OK
"updatedAt": null with empty lists. An unknown or missing provider is 404 provider_not_found; note that the price history answers an unknown slug in providers with 400 invalid_query instead.