What is the CPI?
The Compute Price Index ("CPI") is a public benchmark that tracks the cost of AI inference across major providers. It produces a single equal-weighted reference price — the Standard Compute Unit ("SCU") — calculated from a basket of 22 models across 9 providers.
The Problem
LLM inference pricing is fragmented. Every provider quotes pricing differently — per token, per character, per request, per model. There is no standardized way to benchmark or compare the cost of AI computation across models and providers. You need a verifiable pricing reference you can audit independently.
The Solution
The CPI is an equal-weighted basket of 22 AI models across 9 providers that produces a single, verifiable unit of account: the Standard Compute Unit (SCU). The SCU represents the USD cost of a reference workload, 1,000 input tokens + 500 output tokens, taken as the geometric mean across the full basket.
Key Properties
- Diversified — 22 models across 9 providers prevent any single provider from dominating the index.
- Outlier-resistant — The geometric mean dampens any single model's impact, and the one-family-one-slot rule prevents version pile-up. No caps needed; the math does the work.
- Versioned — The equal-weighted basket launches as v1.0 on June 18, 2026. Reconstitution-driven, published on-chain when basket composition or provider rate-card prices change. There is no fixed cadence.
Basket Composition
The CPI tracks 22 models from 9 providers. Every model family gets one slot, the latest version always, and each model is weighted equally. A family is a provider's distinct product line (e.g. openai.gpt, anthropic.claude); the latest released model in each family is its representative. On a new release the representative auto-rolls. The basket updates with a new version number when families are added, removed, or replaced.
alibaba.qwen-flash
Qwen3.6 Flash
alibaba.qwen-max
Qwen3.7-Max
alibaba.qwen-plus
Qwen3.7 Plus
anthropic.claude-fable
Claude Fable 5
anthropic.claude-haiku
Claude Haiku 4.5
anthropic.claude-opus
Claude Opus 5
anthropic.claude-sonnet
Claude Sonnet 5
deepseek.v-flash
V4 Flash
deepseek.v-pro
V4 Pro
google.gemini
Gemini 3.1 Pro
google.gemini-flash
Gemini 3.5 Flash
google.gemini-flash-lite
Gemini 3.1 Flash-Lite
minimax.m
MiniMax M3
moonshot.kimi
Kimi K3
openai.gpt
GPT-5.5
openai.gpt-luna
GPT-5.6 Luna
openai.gpt-mini
GPT-5.4 Mini
openai.gpt-nano
GPT-5.4 Nano
openai.gpt-sol
GPT-5.6 Sol
openai.gpt-terra
GPT-5.6 Terra
xai.grok
Grok 4.5
xiaomi.mimo
MiMo V2.5 Pro
SCU Formula
The Standard Compute Unit is calculated in two steps. The reference workload is fixed at 1000 input + 500 output tokens, evaluated across all basket models.
The SCU is reconstitution-driven. It is published on-chain whenever the basket changes, either because a model is added, removed, or replaced, or because a provider updates a rate-card price. Both triggers produce a new on-chain version. There is no fixed cadence and no continuous off-chain feed.
Step 1 — Per-model cost
For each model in the basket, compute the cost of the reference workload using the provider's published per-token pricing. Prices are USD per 1M tokens.
Step 2 — Equal-Weight Geometric Mean
Take the geometric mean of all N model workload costs. Every model is weighted equally; there are no tiers, no caps, and no provider weights. Each model family holds one slot at its latest version, so a provider cannot inflate its representation by shipping extra SKUs.
Live SCU: $0.003302 — the geometric mean of 22 equal-weighted model costs.
Every published revision permanently carries the methodology version that produced it (currently v1). Definitions and the changelog are served by the methodology endpoint; every oracle response carries the X-Methodology-Version header.
Anyone with access to provider pricing pages can independently reproduce this number.
Read the full methodology specification →Governance
The model-family rule reduces governance to a minimum. One eligibility rule, one family rule, one emergency trigger. No weight committees, no tier reviews.
| Rule | Specification | Frequency |
|---|---|---|
| Listing Criteria | Public GA + first-party USD pricing + in-scope text model + seasoning + liveness. Applied identically to all. | Continuous |
| Model Family Rule | One slot per family, latest GA version auto-wins. No governance needed. | Auto |
| Edge-Case Review | Published, dated decision for family-vs-version edge cases. Stated reasoning. | As Needed |
| Reconstitution | Additions and removals applied by the criteria. Logged. | Scheduled |
| Price Updates | Reflected automatically from first-party price cards. Daily scan. | Daily |
| Emergency Trigger | Any single model that moves price by more than the set threshold in 24 hours enters a short hold before the change is reflected. | As Needed |
Every basket change increments the revisionVersion counter. The full history is available via the GET /v1/oracle/reconstitutions endpoint. On-chain, the OracleRegistry contract records each published revision with its timestamp and metadata hash.
On-Chain Verification
All CPI pricing is recorded on-chain via the OracleRegistry contract on Base. You can independently verify prices without trusting the Compute Finance API.
Contract Address
| Network | Base (Chain ID 8453) |
| Contract | 0x1b91c0961928a14a2eD6c1985bC11aF1b302714D |
Read Functions
| Function | Description |
|---|---|
version() | Oracle implementation version — assert before deserializing tuples |
decimals() | Scale of scuUsd and baseline values (18) |
lastRevisionVersion() | Returns the highest confirmed revision number |
getLatestRevision() | Returns the latest revision header: revisionVersion, methodologyVersion, scuUsd, contentHash, metadataHash, publishedAt |
getRevision(uint256 revisionVersion) | Returns the same revision header tuple for a specific revisionVersion |
getRevisionScuUsd(uint256 revisionVersion) | Returns the SCU value in USD 18-dec for a specific revision |
getBaseline() | Returns the SCU value of the first revision (denominator of the inverse purchasing-power index) |
getComputeIndex() | Returns the latest (baseline / SCU) × 100 |
getRevisionAt(uint256 timestamp) | Returns the revision version active at the given Unix-seconds timestamp |
getComputeIndexAt(uint256 timestamp) | Returns the atomic tuple (scuUsd, indexValue, publishedAt, methodologyVersion, revisionVersion) at the timestamp |
Verification with ethers.js
import { ethers } from "ethers";
const ORACLE_REGISTRY = "0x1b91c0961928a14a2eD6c1985bC11aF1b302714D";
const ABI = [
"function lastRevisionVersion() view returns (uint256)",
"function getLatestRevision() view returns (tuple(uint256 revisionVersion, uint16 methodologyVersion, uint256 scuUsd, bytes32 contentHash, bytes32 metadataHash, uint64 publishedAt))",
"function getBaseline() view returns (uint256)",
"function getComputeIndex() view returns (uint256)"
];
const provider = new ethers.JsonRpcProvider("https://mainnet.base.org");
const oracle = new ethers.Contract(ORACLE_REGISTRY, ABI, provider);
// Read latest revision header
const latest = await oracle.getLatestRevision();
console.log("revisionVersion:", latest.revisionVersion.toString());
console.log("SCU (USD, 18-dec):", ethers.formatUnits(latest.scuUsd, 18));
console.log("metadataHash:", latest.metadataHash);
// Inverse purchasing-power index — (baseline / SCU) × 100
const computeIndex = await oracle.getComputeIndex();
console.log("Compute Index:", ethers.formatUnits(computeIndex, 18));
// Per-model prices live in the off-chain manifest fetched by metadataHash —
// resolve at /v1/oracle/manifest/{metadataHash} and verify with JCS+keccak256.Verification via Basescan
You can also read the contract directly on Basescan. Since OracleRegistry is an upgradeable proxy, use the Read as Proxy tab so the implementation's functions are available:
- Go to Basescan → Contract → Read as Proxy
- Call
getLatestRevision()— its first return value lists every registered model pricing key - Read the on-chain revision header (scuUsd, methodologyVersion, contentHash, metadataHash, publishedAt) via
getRevision(version). Per-model prices live in the off-chain manifest fetched by metadataHash. - Prices are returned in $COMPUTE wei (18 decimals) per 1M tokens. Divide by 10^18 to get the $COMPUTE amount.
Verification via Sourcify
The same source is independently verified on Sourcify, a decentralized verification repository: View on Sourcify ↗
Public API
All oracle endpoints are public and require no authentication. Read access is free and unrestricted. Base URL: https://api.compute.finance
Endpoints
/v1/oracle/scuCurrent SCU value, methodology version, and family-representative breakdown/v1/oracle/modelsCatalog of basket models plus retired ex-members — `inBasket` flag and `retiredAtRevision`; retired models are priced from the live catalog/v1/oracle/models/{key}Single catalog model (basket member or retired) by pricing key/v1/oracle/models/{key}/price-historyPer-model input/output USD price time series — one entry per on-chain revision for basket members, one per catalog price change for every other model (per-revision, daily, or weekly granularity); Accept: text/csv returns a CSV attachment/v1/oracle/catalogEvery tracked model (incl. catalog-only and pricing-only providers) with current price, integrated flag, and index-member flag/v1/oracle/models/{key}/price-at?date={iso8601}Per-model input/output USD price effective at the requested ISO-8601 timestamp; basket members resolve from the attested manifest, all other models from the live catalog — every response labels its source/v1/oracle/basketFull basket composition: all models with equal weights, revision and methodology version/v1/oracle/methodologyActive methodology version and full changelog/v1/oracle/methodology/{version}Single methodology record (formula, family rule, reference workload, spec URL)/v1/oracle/baselineFrozen SCU of the first confirmed revision — the denominator for the inverse computeIndex purchasing-power view/v1/oracle/scu-at?date={iso8601}SCU value active at a given timestamp — step-function lookup of the latest confirmed revision with publishedAt ≤ date (highest revisionVersion on ties)/v1/oracle/history?from={iso8601}&to={iso8601}&granularity={per-revision|daily|weekly}Historical SCU values, one entry per on-chain revision; granularity: per-revision, daily, or weekly; Accept: text/csv returns a CSV attachment/v1/oracle/reconstitutionsNamed basket-change events with version, models, SCU delta/v1/oracle/reconstitutions/exportExport full reconstitution history as a downloadable markdown file/v1/oracle/revisions/{revision}Full OracleRevision record for a specific on-chain revision/v1/oracle/latestLatest confirmed revision summary (version, timestamps, SCU, basket size)/v1/oracle/healthLast revision timestamp, version count, on-chain sync status/v1/oracle/contract-metadataLive OracleRegistry identity — chainId, proxy address, on-chain version(), and keccak256 of the deployed bytecode/v1/oracle/statsPublic aggregate protocol statistics (TVL, users, volume)/v1/oracle/activityLive activity feed of recent protocol events (paginated)/v1/oracle/pricingPer-model pricing in wei and USD per 1M with markupCode Examples
All endpoints are public. No authentication required.
Get Current SCU
curl https://api.compute.finance/v1/oracle/scuList All Models
curl https://api.compute.finance/v1/oracle/modelsGet Single Model
curl https://api.compute.finance/v1/oracle/models/claude-opus-5Historical SCU (date range)
curl "https://api.compute.finance/v1/oracle/history?from=2026-05-18T00:00:00Z&to=2026-06-18T00:00:00Z&granularity=daily"Response Schemas
GET /v1/oracle/scu
{
"scuUsd": 0.002435,
"computeIndex": 100.00,
"referenceWorkload": { "inputTokens": 1000, "outputTokens": 500 },
"methodologyVersion": 1,
"breakdown": {
"methodologyVersion": 1,
"familyRepresentatives": [
{
"family": "openai.gpt",
"modelKey": "gpt-5.5",
"inputPriceUsdPerMillion": 5.0,
"outputPriceUsdPerMillion": 30.0,
"blendedCostUsd": 0.02
}
]
},
"updatedAt": "2026-06-18T12:00:00Z"
}GET /v1/oracle/models
{
"models": [
{
"id": "gpt-5.5",
"displayName": "GPT-5.5",
"provider": { "key": "openai", "name": "OpenAI" },
"family": "openai.gpt",
"integrated": true,
"usdPricePerMillion": { "input": 5.0, "output": 30.0 },
"weiPricePerMillion": { "input": "756430000000000000000", "output": "4538580000000000000000" },
"markedUpUsdPricePerMillion": { "input": 5.25, "output": 31.5 },
"markedUpWeiPricePerMillion": { "input": "794252000000000000000", "output": "4765509000000000000000" },
"releasedAt": "2026-04-01T00:00:00Z",
"cache": null,
"reasoning": null
}
]
}Error catalog
Every API response uses the envelope below on failure. Branch on error.code rather than HTTP status or error.message text — the code taxonomy is stable, message copy may change.
{
"error": {
"message": "The Bearer API key is missing, malformed, or not recognized.",
"type": "invalid_request_error",
"code": "invalid_api_key",
"param": "authorization", // optional, set when the error binds to a field
"details": { ... }, // optional, code-specific structured payload
"issues": [ ... ] // present when one or more fields fail validation
}
}| Code | Status | Type | Meaning | When it occurs |
|---|---|---|---|---|
unauthorized | 401 | invalid_request_error | Authentication is required to access this endpoint. | The session cookie is missing or invalid, the Bearer token is absent, or the timestamp on a signed request is outside the 5-minute freshness window. |
forbidden | 403 | forbidden | The caller is authenticated but is not allowed to perform this action. | The caller lacks the required role, or a request was signed by an address different from the authenticated wallet. |
invalid_signature | 401 | invalid_request_error | The provided signature could not be verified. | The EIP-191 signature is malformed, truncated, or does not recover to a valid signer. |
signature_reused | 409 | invalid_request_error | This signed request has already been submitted. | The nonce for this signed request was consumed by an earlier submission. |
invalid_api_key | 401 | invalid_request_error | The Bearer API key is missing, malformed, or not recognized. | The token is empty, does not use the `ct_live_` format, or does not match any active key. |
api_key_frozen | 403 | forbidden | The API key is currently frozen and cannot be used for requests. | The key was frozen from the API keys page or by support. Reactivate it from the API keys page, or contact support if it was frozen by an administrator. |
api_key_revoked | 401 | invalid_request_error | The API key has been revoked and can no longer be used. | The key was revoked from the API keys page. Revocation is permanent — issue a new key to continue. |
model_restricted | 403 | forbidden | The requested model is not in this key's allowed-models list. | The key was restricted to a specific set of models; the request referenced a model outside that set. |
bad_request | 400 | invalid_request_error | The request is invalid in a way that does not match a more specific error code. | A generic 400 for request-shape issues that no other code describes more precisely. |
validation_failed | 422 | invalid_request_error | The request body failed validation. Per-field details are in `error.issues[]`. | One or more fields are missing, of the wrong type, or outside their allowed range. |
method_not_allowed | 405 | invalid_request_error | The endpoint exists but does not accept this HTTP method. | A request used a method the route does not support; the `Allow` response header lists the accepted methods. |
not_found | 404 | not_found | The requested resource does not exist. | The identifier did not match any resource, or the URL does not match any endpoint. |
already_exists | 409 | conflict | A resource with the same unique identity already exists. | A duplicate was detected during pre-check, or a concurrent write violated a unique constraint. |
conflict | 409 | conflict | The resource was modified concurrently; retry with the latest version. | A serializable transaction aborted due to concurrent writes, or an operation found the resource in an inconsistent state. |
insufficient_balance | 402 | insufficient_quota | The account's $COMPUTE balance is below the requested amount. | Triggered when withdrawing more than the balance, or when an inference request would exceed the balance after billing. |
spending_limit_reached | 429 | rate_limit_error | A per-key spending cap has been reached. | The key carries a daily, weekly, or monthly cap, and this request would exceed it. |
all_keys_exhausted | 502 | server_error | No upstream capacity is currently available for the routed model. | All contributor keys serving this model were unavailable, rate-limited, or in a cool-down; retry shortly. |
rate_limited | 429 | rate_limit_error | The caller exceeded a rate-limit window on this endpoint. | Either the per-endpoint request-rate cap or the provider-pool RPM/TPM cap was hit. |
stream_interrupted | 500 | server_error | The SSE stream aborted before completion. | The upstream provider connection dropped mid-stream. This error is delivered inside the SSE body, not as an HTTP status. |
contract_error | 500 | server_error | An on-chain call reverted or could not be confirmed. | The transaction failed to broadcast, timed out waiting for a receipt, or the receipt reported failure. |
internal_error | 500 | server_error | An unexpected server-side failure occurred. | A fallback for exceptions that no other error code describes; the failure is logged for investigation. |
service_unavailable | 503 | server_error | A required upstream dependency is temporarily unavailable. | A dependency needed for this request is unreachable; security-critical paths intentionally reject rather than degrade. |
Inference API
An OpenAI- and Anthropic-compatible inference API. Point an official openai or @anthropic-ai/sdk client at Compute Finance by swapping the base URL and providing a ct_live_* key. Requests are billed from your $COMPUTE balance.
Base URL: https://api.compute.finance. Swagger UI: /v1/docs/inference · Get a key: https://compute.finance/dashboard/api-keys.
Authentication
Every endpoint accepts Authorization: Bearer ct_live_*. POST /v1/messages also accepts x-api-key: ct_live_* for @anthropic-ai/sdk compatibility.
Every request checks the key's state. A key marked active proceeds normally; a frozen key returns 403 API_KEY_FROZEN; a revoked key returns 401 API_KEY_REVOKED; anything unknown or malformed returns 401 INVALID_API_KEY. If a key is restricted to a specific set of models and the request references another, the response is 403 MODEL_RESTRICTED.
Endpoints
/v1/chat/completionsBearer ct_live_*OpenAI Chat Completions wire format, streaming or non-streaming./v1/messagesBearer / x-api-keyAnthropic Messages API wire format, streaming or non-streaming./v1/modelsRoutable model catalog in OpenAI format./v1/usageBearer ct_live_*Per-key balance and daily / weekly / monthly limits./v1/inference/estimateReturns an up-front cost preview: creditsCost, creditsWei, usdCost.Wire-format deltas
Requests are validated before dispatch. Unsupported or malformed params return 422 VALIDATION_FAILED with the offending field in the error body — no tokens are billed.
Provider capability gating. Advanced features (tools, structured outputs) only work on providers that support them natively — currently openai and anthropic. A single named model on another provider returns 422 VALIDATION_FAILED; inside a models[] list, such an entry is skipped and the request fails only if no listed entry supports the feature.
Client fallback list. Send models — an ordered list of catalogue ids (1–8); model, when present, is tried first, then each entry in turn. An entry lacking capacity or a requested capability is skipped; the request is billed at the model that answered (the hold covers the costliest listed entry, the excess is released at settlement), and the served model is returned in the body and the X-Model-Used header. Combining a list with model:auto is rejected. Limitations: a prompt exceeding an entry's context window, or a parameter an entry rejects as invalid, aborts the request rather than falling through — fall-through covers capacity and capability, not 422-class input errors.
OpenAI Chat Completions
Supported params: model, messages, stream, response_format, tools, tool_choice, parallel_tool_calls, plus the standard sampling / limit / logprobs family.
Also accepted: models (ordered fallback list, 1–8 entries), conversation_id.
Not supported (422): legacy functions / function_call (use tools / tool_choice), n > 1, multimodal content arrays.
Anthropic Messages
Supported params: model, messages, max_tokens, system, stream, tools, tool_choice, plus stop_sequences, metadata.user_id, and the sampling family (temperature, top_p, top_k).
Content blocks: text, tool_use, tool_result; cache_control is honored. Also accepted: models (ordered fallback list). Extra fields on message objects are rejected with 422.
Streaming
Both endpoints stream Server-Sent Events (Accept: text/event-stream) when stream: true. Wire formats differ (OpenAI vs Anthropic).
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"gpt-5.5","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"gpt-5.5","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
...
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"gpt-5.5","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":10,"completion_tokens":5,"total_tokens":15},"x_credits_used":"1234","x_credits_remaining":"98765","x_ratelimit_requests_remaining":123}
data: [DONE]event: message_start
data: {"type":"message_start","message":{"id":"msg_...","type":"message","role":"assistant","content":[],"model":"claude-opus-4-1","stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":10,"output_tokens":0}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":5}}
event: message_stop
data: {"type":"message_stop"}Stop reasons are translated between wire formats: OpenAI stop ↔ Anthropic end_turn; length ↔ max_tokens; tool_calls ↔ tool_use.
The streaming final chunk also mirrors x_credits_used, x_credits_remaining, and x_ratelimit_requests_remaining into the body.
Response headers
| Header | Meaning |
|---|---|
X-Compute-Used | Wei debited for this request after settlement. |
X-Compute-Remaining | Remaining $COMPUTE balance for the buyer account, in wei. |
X-Key-Daily-Remaining | Remaining daily spending cap for this key, in wei — `unlimited` if unset. |
X-Key-Weekly-Remaining | Remaining weekly spending cap for this key. |
X-Key-Monthly-Remaining | Remaining monthly spending cap for this key. |
X-RateLimit-Limit | Ceiling of the tightest active rate-limit bucket. |
X-RateLimit-Remaining | Remaining capacity in the tightest bucket. |
X-RateLimit-Reset | Epoch seconds when the tightest bucket resets. |
Errors
Every error response follows the envelope below. Branch on error.code rather than HTTP status — several codes can share the same status.
{
"error": {
"message": "The Bearer API key is missing, malformed, or not recognized.",
"type": "invalid_request_error",
"code": "invalid_api_key",
"param": "authorization", // optional, set when the error binds to a field
"details": { ... }, // optional, code-specific structured payload
"issues": [ ... ] // present when one or more fields fail validation
}
}| Code | Status | Type | Meaning | When it occurs |
|---|---|---|---|---|
invalid_api_key | 401 | invalid_request_error | The Bearer API key is missing, malformed, or not recognized. | The token is empty, does not use the `ct_live_` format, or does not match any active key. |
api_key_frozen | 403 | forbidden | The API key is currently frozen and cannot be used for requests. | The key was frozen from the API keys page or by support. Reactivate it from the API keys page, or contact support if it was frozen by an administrator. |
api_key_revoked | 401 | invalid_request_error | The API key has been revoked and can no longer be used. | The key was revoked from the API keys page. Revocation is permanent — issue a new key to continue. |
model_restricted | 403 | forbidden | The requested model is not in this key's allowed-models list. | The key was restricted to a specific set of models; the request referenced a model outside that set. |
validation_failed | 422 | invalid_request_error | The request body failed validation. Per-field details are in `error.issues[]`. | One or more fields are missing, of the wrong type, or outside their allowed range. |
method_not_allowed | 405 | invalid_request_error | The endpoint exists but does not accept this HTTP method. | A request used a method the route does not support; the `Allow` response header lists the accepted methods. |
insufficient_balance | 402 | insufficient_quota | The account's $COMPUTE balance is below the requested amount. | Triggered when withdrawing more than the balance, or when an inference request would exceed the balance after billing. |
spending_limit_reached | 429 | rate_limit_error | A per-key spending cap has been reached. | The key carries a daily, weekly, or monthly cap, and this request would exceed it. |
all_keys_exhausted | 502 | server_error | No upstream capacity is currently available for the routed model. | All contributor keys serving this model were unavailable, rate-limited, or in a cool-down; retry shortly. |
rate_limited | 429 | rate_limit_error | The caller exceeded a rate-limit window on this endpoint. | Either the per-endpoint request-rate cap or the provider-pool RPM/TPM cap was hit. |
stream_interrupted | 500 | server_error | The SSE stream aborted before completion. | The upstream provider connection dropped mid-stream. This error is delivered inside the SSE body, not as an HTTP status. |
service_unavailable | 503 | server_error | A required upstream dependency is temporarily unavailable. | A dependency needed for this request is unreachable; security-critical paths intentionally reject rather than degrade. |
Rate limits
Per-key. Each API key can carry optional daily, weekly, and monthly $COMPUTE caps. Exceeding any cap returns 429 SPENDING_LIMIT_REACHED; the remaining budget is exposed in the X-Key-*-Remaining headers.
Per-pool. Each provider pool has RPM and TPM ceilings. Exceeding either returns 429 RATE_LIMITED.
GET /v1/inference/estimate is throttled to 10 requests per second per source IP; it requires no authentication and does not consume $COMPUTE.
Billing
Cost is estimated up-front, reserved from the balance, then settled against actual token usage. The X-Compute-Used and X-Compute-Remaining headers report the final debit and remaining balance. An insufficient balance returns 402; hitting a per-key or per-account cap returns 429.
Models
GET /v1/models returns the routable catalog in OpenAI format. Use id (or a value from routingAliases) as the model parameter. Setting model: "auto" enables content-based auto-routing. The full catalog with prices is available at https://api.compute.finance/v1/oracle/catalog.
Quickstarts
Snippets use pinned SDK versions. Replace ct_live_... with a key issued at https://compute.finance/dashboard/api-keys.
from openai import OpenAI
client = OpenAI(
base_url="https://api.compute.finance/v1",
api_key="ct_live_...",
)
resp = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.compute.finance/v1",
apiKey: process.env.COMPUTE_FINANCE_API_KEY!, // ct_live_...
});
const resp = await client.chat.completions.create({
model: "gpt-5.5",
messages: [{ role: "user", content: "Hello" }],
});
console.log(resp.choices[0].message.content);from anthropic import Anthropic
client = Anthropic(
base_url="https://api.compute.finance",
api_key="ct_live_...",
)
resp = client.messages.create(
model="claude-opus-4-1",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
print(resp.content[0].text)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.compute.finance",
apiKey: process.env.COMPUTE_FINANCE_API_KEY!, // ct_live_...
});
const resp = await client.messages.create({
model: "claude-opus-4-1",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
});
console.log(resp.content[0].text);curl https://api.compute.finance/v1/chat/completions \
-H "Authorization: Bearer ct_live_..." \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Hello"}]}'Machine-readable specifications
OpenAPI YAML · OpenAPI JSON · llms-full.txt
Model Context Protocol (MCP)
AI agents can query the oracle, estimate costs, and analyze sessions through the official Compute Finance MCP server. Stdio transport, no API key required.
Install in any MCP client: npx @compute-finance/mcp
Client config snippet: {"command":"npx","args":["@compute-finance/mcp"]}
Claude Code one-liner (registers MCP + skills + cost hook): npx @compute-finance/mcp setup
Read-only tools across five layers:
- data — Live oracle data — basket, price, SCU, CPI, reconstitutions
- compute — Cost estimation and cross-model comparison
- render — Pre-formatted session reports used by the Claude Code skills
- analyze — Raw JSON session and per-inference breakdown
- history — Aggregate stats across logged sessions
Bundled Claude Code slash skills:
/cf-session-management— Measured post-session cost analysis/cf-session-consumption— Per-inference token spend breakdown/cf-active-sessions— Multi-session overview across projects
Reference: github.com/compute-finance/mcp · /.well-known/mcp/server-card.json
Compute Finance ID
Your Compute Finance ID (CF ID) is your identity across all Compute Finance surfaces. Created on first sign-in via email or wallet, it ties together your profile, points balance, and referral code into a single record.
What CF ID stores
| Field | Description |
|---|---|
cf_id | Public identifier — format: cf_usr_XXXXXXXXXXXX |
email | Used for notifications. Optional for wallet-only sign-in. |
wallet_address | On-chain address on Base. Created via account abstraction or connected externally. |
display_name | User-chosen name. Defaults to a truncated email or wallet address. |
referral_code | Permanent 8-character code — format: cf_ref_XXXXXXXX |
points_balance | Current points total, denormalized from the points ledger |
Sign-in flows
Two sign-in methods, both produce a CF ID:
- Email — Enter your email, receive a 6-digit code, verify. A smart wallet is created on Base and associated with your email. No seed phrase required.
- Wallet — Connect MetaMask, Coinbase Wallet, or any WalletConnect-compatible wallet. Sign a SIWE message. Your wallet address becomes your CF ID's primary identifier.
Both flows converge on the same CF ID record. You can add an email to a wallet-only account later from your settings.
Points
Points track your engagement with Compute Finance — signup, daily logins, oracle interactions, and referrals. As your balance grows, you unlock higher tiers. Points are append-only and recorded in a public ledger per CF ID.
Tiers
| Tier | Min Points |
|---|---|
| Explorer | 0 |
| Starter | 500 |
| Builder | 2,000 |
| Architect | 5,000 |
| Titan | 15,000 |
How points are earned
V1 supports six earning channels. New channels will be added in future versions and announced via the changelog.
| Channel | Amount | Trigger | Frequency |
|---|---|---|---|
| Signup bonus | 100 pts | CF ID created | Once per account |
| Referral (referrer) | 250 pts | Referred user completes signup | Per successful referral |
| Referral (referred user) | 50 pts | User signs up via referral link | Once per account |
| Daily login | 10 pts | User logs in on a new calendar day (UTC) | Once per day |
| 7-day login streak bonus | 50 pts | User logs in 7 consecutive days | Once per streak completion |
| Oracle interaction | 5 pts | User views a unique model’s pricing on the oracle page | Up to 12 per day (one per model) |
Ledger model
The points ledger is an append-only log. No entries are ever updated or deleted. Your canonical points balance is the sum of all your ledger entries. The denormalized points_balance field on your CF ID record is a performance optimization that is reconciled periodically.
| Field | Type | Description |
|---|---|---|
id | UUID | Primary key |
cf_id | String (FK) | The user who earned the points |
type | Enum | One of: signup, referral, referral_welcome, daily_login, streak_bonus, oracle_interaction |
amount | Integer | Points earned (always positive — append-only, no negative entries) |
source | String | Human-readable source descriptor (e.g. referral:cf_usr_a3k9m2x7p1b4, oracle:gpt-5.5) |
created_at | Timestamp | When the points were earned |
The append-only design means: no points can be silently removed or altered, the complete earning history is preserved and queryable, and any future audit can reconstruct the exact points balance at any point in time.
Streaks
Use Compute Finance on consecutive calendar days to build a streak. Longer streaks earn bonus points. Your current streak and longest streak are shown in your profile. Streaks reset if you miss a calendar day (UTC).
Leaderboard
The top 50 users by total points are displayed on the public leaderboard, refreshed periodically. The leaderboard shows display name and points only — no other profile data is exposed.
Non-transferability
Points are non-transferable in V1. They have no monetary value, are not convertible to any token or currency, and cannot be sold, traded, or assigned to another account. A points-to-credits conversion ratio for V2 will be announced before V2 ships, and the append-only ledger ensures all V1 earning history is preserved and can be converted accurately at that time.
API endpoints
Points data is queryable via the following endpoints. Authentication is required for endpoints that return personal data; the leaderboard is public.
/v1/pointsYour points summary (total, tier, current streak, longest streak)/v1/points/historyPaginated points ledger entries for your CF ID/v1/points/leaderboardTop 50 users by total points (public, no auth)Referral Program
Every CF ID includes a unique referral code (8 characters). Share your link to invite new users — both sides earn points. The program uses first-touch attribution with a 30-day cookie window.
Referral rewards
| Event | Points | Who Earns |
|---|---|---|
| New user signs up with your code | 50 pts | New user (welcome bonus) |
| You referred a new user | 250 pts | Referrer |
Sharing your referral link
// Referral URL format
https://compute.finance/r?c=cf_ref_XXXXXXXXFind your referral code in your Compute Finance ID settings. Share buttons are available for X, LinkedIn, Telegram, and copy-to-clipboard. The link uses a 30-day attribution cookie — referrals count when the referred user creates a CF ID within 30 days of clicking your link.
Attribution model
Referral attribution is first-touch with a 30-day window. The first referral link a user clicks is the one credited if they sign up within the window. Subsequent referral links from other users do not overwrite the original cookie.
How it works step by step:
- A user visits
https://compute.finance/r?c=cf_ref_XXXXXXXX - The server redirects to
https://compute.financeand sets a cookie:cf_ref=cf_ref_XXXXXXXXwithMax-Age=2592000(30 days),SameSite=Lax,Secure - The click is recorded in the database with the referral code, timestamp, hashed IP address, and user agent
- If the user signs up within 30 days — even if they navigate directly to
https://compute.financewithout the referral link — the cookie is read during CF ID creation and the referral relationship is stored - If the user has already clicked a different referral link, the first-touch cookie is preserved
Anti-gaming rules
The referral program enforces several rules to prevent farming and abuse. None of these rules surface error messages — invalid referrals are silently ignored to avoid leaking information about user accounts.
| Rule | Implementation |
|---|---|
| No self-referral | If the cf_ref cookie matches the signing-up user's own referral code, the referral is silently ignored |
| Email deduplication | One CF ID per email — a user cannot create multiple accounts with the same email to farm referral points |
| IP rate limiting | Maximum 10 CF ID creations per IP address per 24 hours, preventing mass account creation from a single source |
| Click rate limiting | Maximum 100 clicks per referral code per hour. Clicks beyond the limit are not recorded. |
| Disposable email detection | Optional: reject signups from known disposable email domains (mailinator, guerrillamail, etc.) |
Referral dashboard
Your CF ID profile includes a referral dashboard showing:
- Total referral link clicks (all-time)
- Total signups from your referral link
- Conversion rate (signups ÷ clicks)
- Total points earned from referrals
- List of referred users (display name or truncated email, signup date, status: pending or confirmed)
Status transitions
A referral has two possible states. Points are awarded when the status transitions from pending to confirmed:
- pending — The user clicked the referral link but has not yet completed signup
- confirmed — The user has created a CF ID. Points are awarded to both sides within 60 seconds of confirmation.
