<img src="https://cloud.trycorpus.ai/mark.svg" alt="corpusAI" width="40" height="40" />

# corpusAI Cloud Pricing API

*Software that outlives its owners.* Built and operated by [corpusAI](https://www.trycorpus.ai).

Spot price history for AWS, GCP and Azure at every depth: price-change events
since 2026, daily series since 2022 (AWS) / 2024 (all providers), monthly since
2014 (legacy AWS types). Sold per call in USDC over
[x402](https://x402.org) with settlement through Circle Gateway. No signup, no API
key: an unpaid request answers `402 Payment Required` with the payment
requirements, an x402-capable client pays and retries.

- Base URL: `https://cloud.trycorpus.ai/v1`
- OpenAPI 3.1: `https://cloud.trycorpus.ai/openapi.json`
- Prices: **0.010000 USDC** per call for events, hourly bars, single-type latest price, on-demand and reserved history of a type, and Azure eviction; **0.050000 USDC** for the full daily or monthly spot history of a type; **0.100000 USDC** for a whole-region snapshot (spot, on-demand or reserved); bulk: **1.00 USDC** for every region of a provider, **3.00 USDC** for a region's legacy history file, **0.50 USDC** for a region-day of raw events. Discovery endpoints are free.
- Free dashboard (daily averages, precision decays with age): `https://tools.traversa.dev/cloud-pricing`
- Contact: julian@traversa.dev · [trycorpus.ai](https://www.trycorpus.ai)

## Quick start for agents

MCP server (Claude Code, Claude Desktop, Cursor, any MCP client), published as
[`corpus-cloud-pricing-mcp`](https://www.npmjs.com/package/corpus-cloud-pricing-mcp):

```bash
claude mcp add corpus-cloud-pricing -e CORPUS_PAYER_KEY=0x... -- npx -y corpus-cloud-pricing-mcp
```

Free tools work without a key; paid tools pay automatically from the payer
wallet's Circle Gateway balance (`npx corpus-cloud-pricing-mcp deposit 2.00`
to fund it once). Or call the API directly:

```bash
# 1. What exists? (free)
curl -s "https://cloud.trycorpus.ai/v1/catalog"
curl -s "https://cloud.trycorpus.ai/v1/instances?provider=aws&region=us-east-1&prefix=c5."

# 2. An unpaid paid call returns 402 with x402 v2 requirements (header + body)
curl -si "https://cloud.trycorpus.ai/v1/spot/events?provider=aws&region=us-east-1&instance=c5.large"

# 3. Pay with the Circle CLI (any Gateway-supported network listed in accepts[])
circle services inspect "https://cloud.trycorpus.ai/v1/spot/events?provider=aws&region=us-east-1&instance=c5.large"
circle services pay "https://cloud.trycorpus.ai/v1/spot/events?provider=aws&region=us-east-1&instance=c5.large" \
  -X GET --address <your-wallet> --chain <CHAIN-FROM-INSPECT> --max-amount 0.010000 --output json
# (use --max-amount 0.050000 for /spot/daily and /spot/monthly, 0.100000 for /spot/snapshot)
```

Any x402 v2 client works (`@circle-fin/x402-batching` `GatewayClient`, `@x402/fetch`,
the Circle CLI). Payment is verified and settled before the handler runs; a 400 or
404 is never charged.

## Endpoints

| Method | Path | Cost | What |
|---|---|---|---|
| GET | `/health` | free | liveness + `ready` flag |
| GET | `/catalog` | free | providers, region slugs, coverage window, event counts |
| GET | `/instances?provider&region[&prefix]` | free | exact instance type names in a region |
| GET | `/spot/events?provider&region&instance[&from&to&az&product&include_repeats&limit]` | 0.010000 | raw price-change events |
| GET | `/spot/hourly?provider&region&instance[&from&to]` | 0.010000 | hourly time-weighted OHLC bars |
| GET | `/spot/daily?provider&region&instance[&from&to]` | 0.050000 | full daily history, all eras stitched, `source` per row |
| GET | `/spot/monthly?provider&region&instance[&from&to&include_archive]` | 0.050000 | full monthly history back to 2014 (AWS legacy types) |
| GET | `/spot/latest?provider&region&instance` | 0.010000 | price currently in force per (zone, product) for one type |
| GET | `/spot/snapshot?provider&region` | 0.100000 | current price of every type, zone and product in a region |
| GET | `/azure/eviction?region[&sku&from&to]` | 0.010000 | Azure 28-day eviction-rate buckets, daily samples |
| GET | `/spot/snapshot/all?provider` | 1.00 | current spot price of every type and zone in every region of a provider |
| GET | `/spot/export/history?provider&region` | 3.00 | gzip TSV: legacy daily + monthly history of every type in a region |
| GET | `/spot/export/events?provider&region&date` | 0.50 | gzip TSV: every raw event of a region for one UTC day |
| GET | `/ondemand?provider&region&instance` | 0.010000 | on-demand list-price change history of one type |
| GET | `/ondemand/snapshot?provider&region` | 0.100000 | current on-demand list price of every type in a region |
| GET | `/reserved?region&instance[&provider&ri_type]` | 0.010000 | reserved effective hourly price history: AWS RIs (1y/3y, no/all upfront), Azure reservations |
| GET | `/reserved/snapshot?region[&provider]` | 0.100000 | current reserved prices of every type and ri_type in a region |
| GET | `/gpu/models` | free | GPU models with rental quotes and the providers quoting them |
| GET | `/gpu/quotes?gpu[&provider&market]` | 0.010000 | latest rental quotes for one GPU model across neo-clouds and marketplaces |
| GET | `/gpu/index?gpu[&from&to]` | 0.050000 | daily lo/median/mean/hi per provider and market, with aws-spot / gcp-spot legs |
| GET | `/gpu/snapshot` | 0.100000 | every GPU × provider × market in one call |
| GET | `/index/tickers` | free | every index ticker with segment definitions |
| GET | `/index/fixing?ticker[&day]` | 0.010000 | one day's fixing: median, low, high, count |
| GET | `/index/history?ticker[&from&to]` | 0.050000 | daily fixings; SPOT tickers back to 2022 |
| GET | `/index/board[?day]` | 0.100000 | every ticker's fixing for a day |
| GET | `/status` | free | freshness of every source |
| GET | `/capacity/stress?gpu&day` | 0.010000 | capacity stress score, 0 slack to 100 tight, with components |
| GET | `/capacity/history?gpu&from&to` | 0.050000 | daily stress scores for one GPU |
| GET | `/capacity/board?day` | 0.100000 | every GPU's score for one day, tightest first |
| GET | `/tokens/models` | free | every LLM with a token price fixing, ticker codes, today's range |
| GET | `/tokens/quotes?model&day` | 0.010000 | every source and host's price for one model, USD per million tokens |
| GET | `/tokens/fixing?ticker&day` | 0.010000 | one day's fixing, `CX.TOK.<MODEL>.IN`, `.OUT` or `.BLEND` |
| GET | `/tokens/history?ticker&from&to` | 0.050000 | daily fixings for a token ticker |
| GET | `/tokens/board?day` | 0.100000 | every model's input, output and blended fixing plus the frontier basket |
| GET | `/term/instance?provider&region&instance` | 0.010000 | price ladder: spot, on-demand, 1y, 3y with discounts |
| GET | `/term?gpu` | 0.050000 | term structure per hyperscaler for a GPU, USD per GPU-hour |

Parameters are query strings. `provider` is `aws`, `gcp` or `azure`; `region` and
`instance` must match `/catalog` and `/instances` exactly. Times are ISO 8601 UTC
(`from` inclusive, `to` exclusive). Prices are USD per hour.

## Eras and sources

Every daily and monthly row carries a `source`. `/catalog` returns the same
legend as `sources`.

| source | What | Window | Standing |
|---|---|---|---|
| `direct` | price-change events pulled daily from the provider APIs; the only source with zones, timestamps and intraday range | AWS from 2026-06-06, GCP from 2026-04-08, Azure from 2025-07 (per SKU) | measured |
| `titans` | SpotLake TITANS daily sample average (the dashboard's dense series) | AWS 2024-02 to 2026-06-05, GCP 2024-01 to 2026-04-07, Azure until each SKU's first direct event | third-party daily average, no range |
| `pauley` | AWS raw price-change events (Pauley dataset, CC-BY) time-weighted per day, Linux/UNIX; open/high/low/close on days the price moved | 2022-05-31 to 2024-01-31 | measured |
| `uscisi-adjusted` | USC/ISI monthly archive divided by a per-instance factor fitted on the 2022-2023 overlap; only the ~23 types per region with a stable factor | 2017 to 2022-04 | estimated |
| `archive` | USC/ISI monthly spot dataset as published, open/high/low/close, 51 legacy AWS types per region | 2014-02 to 2023-12 | third-party; averages mix OS products and some rows' origin could not be verified; returned separately by `/spot/monthly`, never blended |

`/spot/daily` returns legacy rows up to the day before the type's first direct
event (`direct_from`) and derived bars from then on. `/spot/monthly` returns
`uscisi-adjusted` months, then months rolled up from the daily series, and the
raw `archive` alongside. `/spot/events`, `/spot/hourly`, `/spot/latest` and `/spot/snapshot` are
`direct` only. The free dashboard shows daily averages for the trailing 90
days, weekly for the trailing year and monthly beyond; the API is where the
full-precision history lives.

## Bulk products

The per-type calls suit targeted questions. For whole-region or whole-provider
work use the bulk products: `/spot/snapshot/all` returns every region of a
provider in one JSON response; `/spot/export/history` streams the store's own
legacy-history file for a region (all types, daily and monthly rows with their
`source`, about 10 MB gzip for an AWS region; only the original three regions
per provider have one); `/spot/export/events` streams one region-day of raw
events exactly as collected (every type, zone and repeat). Pulling a region's
whole direct-era history is therefore one events call per day.

## Index fixings

`/index/*` turn the quotes into citable numbers. A ticker is
`CX.<MODEL>.<SEGMENT>`: `CX.H100SXM.NEO` is the neo-cloud on-demand median for
H100 SXM, `CX.H100SXM.SPOT` the hyperscaler spot composite, and
`CX.H100SXM.SPOT.US-EAST-1` one region. Segments: `MKT` marketplace, `NEO`
neo-cloud on-demand, `INT` interruptible, `HYP` hyperscaler on-demand, `SPOT`
hyperscaler spot. Every fixing carries the methodology version; the method
(eligibility, median aggregation, instance mapping, timing, revisions) is
published at [/methodology](https://cloud.trycorpus.ai/methodology). `SPOT`
histories reach back to 2022 for A100, V100, T4 and A10 and to 2023 for H100,
from measured AWS data.

## Capacity stress

A daily 0 to 100 tightness score per GPU model built from signals the feed
already holds: the share of Shadeform and Lambda listings flagged available,
deployable versus total units on io.net, Vast.ai on-demand offers against
their trailing 30-day median, and the hyperscaler spot-to-on-demand ratio
(spot converges on on-demand when capacity is scarce). The score is the mean
of the components present that day and every component is returned with its
inputs. History starts 2026-09-13.

## LLM token prices

One snapshot a day from four public sources: the OpenRouter catalog, OpenRouter's
per-host endpoints for twenty index models (the same model priced by Azure,
Amazon Bedrock, Google, Together, DeepInfra and others), the LiteLLM price
table, and DeepInfra's model list. Prices are USD per million tokens. A model's
fixing is the median across every source and host at the standard tier; batch
and free variants are stored but excluded from fixings. Tickers are
`CX.TOK.<MODELCODE>.IN`, `.OUT` and `.BLEND` where BLEND is the 3:1
input:output blend, plus `CX.TOK.FRONTIER.*` for the median across the
frontier basket listed by `/tokens/models`. History starts 2026-09-14.

## Term structure

`/term/instance` returns one instance type's ladder from no commitment to
three years: the current spot median across zones, the on-demand list price,
and each reserved or reservation term as an effective hourly price with any
upfront amortised, plus the discount to on-demand. `/term?gpu=` does the same
per GPU-hour for every hyperscaler with a mapped instance family, taking the
median across regions. AWS carries four committed terms (1y/3y × no/all
upfront), Azure two (1y/3y all upfront), GCP two resource-based committed-use
terms (`cud_1y`, `cud_3y`, no upfront) built from the Billing Catalog. Neo-cloud commitment prices are quote-only on their sites and
are not included.

## GPU rental market

`/gpu/*` cover the GPU rental market outside the big three: RunPod (secure and
community tiers, spot), Vast.ai (marketplace: the cheapest 64 on-demand and
bid offers per model, with host reliability and verification), DataCrunch
(on-demand and spot), Lambda, Vultr, Linode and Oracle Cloud list prices.
Quotes are taken from each provider's public price feed once a day and
normalised to USD per GPU-hour under a common model name (`/gpu/models`).
`/gpu/index` puts hyperscaler spot beside them: rows with provider `aws-spot`,
`gcp-spot` or `azure-spot` are our own spot price events for the instance family that
carries the GPU (for example H100 SXM ↔ `p5.48xlarge`, 8 GPUs), divided by
GPUs per node, per region. Quote history starts 2026-09-13; the hyperscaler
legs reach back to the start of the event data.

## List prices (on-demand and reserved)

`/ondemand` and `/reserved` are change-point series: a row is a day the list
price changed and the last row is the price in force. AWS on-demand and
reserved prices come from the AWS Price List API, refreshed weekly, for the
same 13 regions as spot; reserved history reaches back to 2016 in the original
three regions. Azure on-demand and reservation prices come from Microsoft's
public Retail Prices API for every Linux VM SKU in the 9 Azure regions,
refreshed daily since 2026-09-13 (`/reserved?provider=azure`). `ri_type` values: `ri_1y_no_upfront_standard`,
`ri_1y_all_upfront_standard`, `ri_3y_no_upfront_standard`,
`ri_3y_all_upfront_standard`, all standard class, Linux, shared tenancy, with
upfront amortised over the term. GCP and Azure on-demand series are the
TITANS-era feed (2024 to 2026-08) and are not refreshed yet; `/catalog` shows
per-region coverage under `ondemand` and `reserved`.

## Data semantics

- **Events are price changes, not samples.** A price holds from its `ts` until the
  next event in the same `(instance, az, product)` series. AWS reprices roughly
  3.5 times a day per type and zone; GCP about 9 times a year; Azure monthly.
- **`az`** is the AWS zone id (`use1-az1`), the GCP region name, or the Azure
  region name (`eastus`). **`product`** is the OS/product string the price applies
  to (`Linux/UNIX`, `Spot`, `Linux`, ...).
- **Bars** (`/spot/hourly`, `direct` rows of `/spot/daily`) weight each price by how long it was
  in force, per zone, then collapse zones: `open`/`close`/`avg` are the median
  across zones, `high` the max, `low` the min, `dur` the seconds covered. A final
  price is carried forward at most 10 days (AWS) or 400 days (GCP, Azure), so a
  retired type does not grow a flat tail. `avg` is exactly the public dashboard
  value; the other fields exist only here.
- **`/spot/latest`** and **`/spot/snapshot`** return the newest event of every
  series. Check `age_seconds`: an AWS series older than ~10 days is probably
  retired.
- **Coverage** (see `/catalog` for the live list and first/last dates):
  13 AWS regions, 8 GCP regions and 9 Azure regions. The original three per
  cloud (AWS us-east-1, us-west-2, eu-west-1; GCP us-central1, us-east4,
  europe-west4; Azure us-east `eastus`, us-west-2 `westus2`, eu-west
  `westeurope`) carry event-level data from 2026-06-06 (AWS), 2026-04 (GCP),
  2025-07 (Azure), daily history from 2022-05-31 (AWS) and 2024 (GCP, Azure),
  and monthly from 2014-02 (51 legacy AWS types). Regions added in September
  2026 start from their first collection day (the providers expose at most
  90 days back, so there is no deeper backfill). Eviction samples from
  2026-09-05. Collection runs daily at 03:17 UTC and the store is refreshed
  shortly after.
- **Limits**: `/spot/events` returns at most `limit` rows (max 10000); when
  `truncated` is true continue from `next_from`. Hourly windows are capped at
  366 days.

## Pay with a key

The same endpoints, the same prices, without a wallet. A prepaid key
(`ck_live_…`) sent as `X-Api-Key` is charged the per-call price from its USD
balance; every response carries `X-Charge-USD` and `X-Balance-USD`, and
`GET /v1/account` (with the key) returns the balance, the last 31 days of
usage and the last credits. A key with no balance left gets a `402` with the
price and the balance; an unknown or expired key gets `401`.

Getting a key: write to julian@traversa.dev and we send one, or a trial key
with a small balance. Topping up: `GET /v1/billing/packs` lists the credit
packs ($25 buys $25, $100 buys $110, $500 buys $575 of calls); opening
`/v1/billing/topup?pack=100` with your key opens a card checkout, and the
balance is credited the moment the payment completes.

## Payment details

An unpaid request to a paid path returns:

```
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: <base64 JSON, same as the body>
Content-Type: application/json

{"x402Version":2,"resource":{...},"accepts":[{"scheme":"exact","network":"eip155:8453","asset":"<USDC>","amount":"10000","payTo":"<seller>","extra":{...}}, ...]}
```

`accepts[]` lists every network accepted; pay on any one of them. Payments are
signed off-chain (EIP-712 authorisations on a Circle Gateway balance, gasless) and
settled in batches by Circle Gateway. Amounts are USDC atomic units (6 decimals).

## Errors

| Status | Meaning | Charged? |
|---|---|---|
| 400 | bad or missing parameter | no |
| 402 | payment required (see above) | no |
| 404 | unknown region / instance | no |
| 503 | store warming up after a restart, retry in a minute | no |
