Skip to content

Price feed

Two read-only endpoints publish what capacity clears at in your market, so you can tune your ceiling against the going rate instead of blind increments.

Route What it serves
GET /api/market/ticks one row per auction tick (~30s), newest first, 7-day window — the live feed
GET /api/market/history bucketed series, up to 365 days — the trend feed

The machine-readable contract is GET /api/market/openapi.json — the feed's own document, since every cluster kind reads the same feed.

Both take an org API token. "Your market" is the site your cluster trades in — the feed is uniform per market: every caller in it gets the same payload, and nothing caller-specific rides it (your own position lives on the capacity read or the k8s limit price).

Picking the market. A token bound to a cluster reads that cluster's market with no extra input. An org-wide token must pass ?cluster=<one of your clusters> (either kind) on every call — a missing selector is a 422. This is always explicit because your clusters can sit on different sites, and each site is its own market.

Feeds arm per market

Both responses carry an enabled flag. false means the feed is not yet armed for your cluster's market and the data comes empty — not an error.

The price is an index, not a quote

Published prices are what winners were assessed, never bids. Pricing is discriminatory per cluster, so there is no single per-tick clearing price to publish — the feed publishes statistics:

  • price — the volume-weighted mean clearing rate, USD per node-hour. Divide by the response's own gpus_per_node to compare against your per-GPU-hour ceiling.
  • price_min / price_max (ticks only) — the spread of rates assessed that tick.
  • price is null when nothing cleared; 0.0 is a real rate (an uncontended market can clear at zero).
  • gpu_model and gpu_vendor: the GPU class these prices are for and its maker. gpu_model is null while the platform has not set one.

An agent bidding exactly the published mean has no clearing guarantee.

Tailing the live feed

curl -H "Authorization: Bearer $NC_TOKEN" \
  "https://nationalcompute.com/api/market/ticks?limit=50"

Rows carry id (the keyset cursor) and at. Two cursors, mutually exclusive:

  • after_id=<newest id you hold> — tail live: you usually get 0–1 rows.
  • before_id=<oldest id you hold> — page backward; next_before_id in the response is the next page's cursor (null = exhausted).

Passing both is a 422. The MCP server's market_read source=ticks takes the same two cursors and limit, and its grid_api get /api/market/ticks passes them through unchanged.

The trend feed

curl -H "Authorization: Bearer $NC_TOKEN" \
  "https://nationalcompute.com/api/market/history?hours=168"

Returns t0 (epoch seconds of the first bucket), step (bucket width in seconds — it grows with the window), and price[] (volume-weighted mean per bucket, null where nothing cleared).

The tuning loop

  1. Read the going rate here.
  2. Read your position on GET /api/vm/capacity (declared ceiling, pending, allocations).
  3. Adjust the ceiling on the capacity PUT (or the k8s limit price). A ceiling under the going rate leaves capacity pending and can shed nodes you hold.
  4. Check what you actually pay on GET /api/billing/balance: the hourly rate the meter last assessed, by kind, cluster and unit price.