Skip to content

Models & Pricing API ​

A public, anonymous aggregation endpoint for the model catalog and published prices, following the OpenRouter Providers specification — ready to be crawled programmatically by third-party price aggregators or clients.

Overview ​

/v1/models/pricing is a public, anonymous aggregation endpoint that outputs all models currently available on the platform together with their published prices. The response follows the OpenRouter Providers specification and can be consumed programmatically by any third-party platform or client.

This endpoint is the "published price" entry point and carries no user identity. The prices returned are the final transaction prices (USD) of the default group (default), consistent with anonymous crawling scenarios. The actual prices paid by logged-in users include user group and tier discount contexts — please refer to the console pricing page.

Use Cases ​

ScenarioDescription
Third-party price aggregationPrice aggregators crawling the platform's model catalog and published prices
Client displayThird-party apps, bots, and SDKs displaying the available model list
Monitoring & alertingMonitoring changes to the platform's models / prices

Endpoint Definition ​

ItemValue
URLhttps://api.calgine.com.cn/v1/models/pricing
MethodGET
AuthNone (public, anonymous)
Rate LimitStrict per-IP rate limit
Caching60-second server-side cache; response includes Cache-Control: public, max-age=60

Request Examples ​

bash
curl https://api.calgine.com.cn/v1/models/pricing
python
import requests

resp = requests.get("https://api.calgine.com.cn/v1/models/pricing", timeout=10)
data = resp.json()["data"]
for m in data[:3]:
    print(m["id"], m["pricing"])
js
const resp = await fetch("https://api.calgine.com.cn/v1/models/pricing");
const { data } = await resp.json();
console.log(data.slice(0, 3).map((m) => ({ id: m.id, pricing: m.pricing })));
go
package main

import (
	"encoding/json"
	"net/http"
)

type ModelEntry struct {
	ID      string                 `json:"id"`
	Name    string                 `json:"name"`
	Pricing map[string]interface{} `json:"pricing"`
}

func main() {
	resp, _ := http.Get("https://api.calgine.com.cn/v1/models/pricing")
	defer resp.Body.Close()
	var body struct{ Data []ModelEntry }
	_ = json.NewDecoder(resp.Body).Decode(&body)
	_ = body
}

Response Structure ​

The top-level structure is always wrapped in a data array:

json
{
  "data": [
    {
      "id": "gpt-4o",
      "name": "GPT-4o",
      "created": 1715558400,
      "input_modalities": ["text", "image"],
      "output_modalities": ["text"],
      "quantization": "unknown",
      "context_length": 128000,
      "max_output_length": 16384,
      "pricing": {
        "prompt": "0.0000025",
        "completion": "0.00001",
        "request": "0",
        "image": "0",
        "input_cache_read": "0.00000125"
      },
      "supported_sampling_parameters": [
        "temperature", "top_p", "frequency_penalty", "presence_penalty",
        "stop", "seed", "max_tokens", "logit_bias", "response_format",
        "tools", "tool_choice", "parallel_tool_calls", "logprobs", "top_logprobs"
      ],
      "supported_features": ["tools", "json_mode", "structured_outputs", "logprobs"]
    }
  ]
}

Top-Level Fields ​

FieldTypeDescription
dataArray<Model>Array of model entries; an empty array means no models are currently published

Model Object Fields ​

FieldTypeRequiredDescription
idstring✅Unique model identifier; use this value when calling /v1/chat/completions
namestring✅Display name (e.g., GPT-4o); falls back to id when not configured
createdint64✅Model release time (Unix seconds)
input_modalitiesstring[]✅Supported input modalities; includes at least text
output_modalitiesstring[]✅Supported output modalities; includes at least text
quantizationstring✅Quantization method (fp16 / fp8 / bf16 / int8 / unknown)
context_lengthint✅Maximum context window in tokens
max_output_lengthint✅Maximum output tokens per response
pricingPricing✅Pricing object, see below
pricing_tiersPricing[]Tiered pricing array (at most 1 element, only output when a threshold is explicitly marked)
supported_sampling_parametersstring[]✅Supported sampling parameters (e.g., temperature, top_p)
supported_featuresstring[]✅Supported feature enums (see the table below)
deprecation_datestringPlanned deprecation date (ISO 8601, YYYY-MM-DD)
hugging_face_idstringHugging Face repository ID for open-source models

Pricing Object Fields ​

All prices are expressed as USD strings. Token-based fields use USD / token; flat-fee field units are listed in the description column.

FieldTypeRequiredUnitDescription
promptstring✅USD / input tokenInput token unit price
completionstring✅USD / output tokenOutput token unit price
requeststring✅USD / requestFixed fee per request (for per-request models)
imagestring✅USD / imageImage generation unit price (per image)
audiostringUSD / audioAudio generation unit price (per segment)
videostringUSD / videoVideo generation unit price (per segment)
web_searchstringUSD / queryBuilt-in web search tool call unit price
internal_reasoningstringUSD / reasoning tokenReasoning token unit price (o1 / Claude thinking series)
input_cache_readstringUSD / tokenCache hit read unit price
input_cache_writestringUSD / tokenCache write unit price (most expensive window published)
min_contextinttokensOnly used by pricing_tiers elements; marks the minimum context length that triggers this pricing tier
  • Missing fields may be returned as "0" (the four base fields prompt / completion / request / image are always present) or omitted entirely (optional fields)
  • "0" can mean either "free" or "this dimension is not supported by the model" — please evaluate together with supported_features and supported_sampling_parameters

supported_features Enum ​

ValueMeaning
toolsSupports tool calling (Function Calling)
reasoningSupports reasoning process (reasoning_content / thinking)
json_modeSupports JSON mode output
structured_outputsSupports structured outputs (Schema constrained)
logprobsSupports returning token log probabilities
web_searchSupports the built-in web search tool

Mapping of the Three Billing Modes ​

The platform supports three billing modes (see Pricing), all of which map onto OpenRouter specification fields:

Internal Billing ModeOutput FieldsDescription
Per Tokenprompt / completion / internal_reasoning / input_cache_read / input_cache_write / web_searchText, Embedding, and similar models; token unit prices are converted from "USD / million tokens" to "USD / token"
Per Requestimage / video / audio / requestRouted automatically by unit type: image generation → image, video generation → video, music/speech → audio, everything else → request
Per Secondrequest / video / audioConverted to a "published price per request" using a typical use-case duration (e.g., 30 seconds); actual billing remains real seconds × unit price, so reconciliation never drifts

Price Calculation ​

Published price formula:

final_usd = base_price × group_ratio × currency_factor
  • base_price: The official price configured in the backend
  • group_ratio: The group multiplier of the default group (default)
  • currency_factor: If the base is configured in CNY, it is converted to USD at the exchange rate; if configured in USD, it remains unchanged
  • Not included: Reseller markups, user tier discounts, user-specific multipliers, time-of-day multipliers, or runtime dynamic factors

The actual amount paid by logged-in users may differ from the published price: users in other groups, with tier discounts, or accessing via a reseller domain will see different prices. Anonymous crawling only reflects the platform's base published price.

Tiered Pricing ​

Some models have different unit prices in different context-length ranges (e.g., the Gemini Pro series charges more at long-context tiers). The "high tier" prices of such models are output via the pricing_tiers array:

json
{
  "id": "gemini-2.5-pro",
  "pricing": {
    "prompt": "0.00000125",
    "completion": "0.00001",
    "request": "0",
    "image": "0"
  },
  "pricing_tiers": [
    {
      "min_context": 200000,
      "prompt": "0.0000025",
      "completion": "0.000015",
      "request": "0",
      "image": "0"
    }
  ]
}
  • pricing is the base tier (the one with the lowest threshold)
  • pricing_tiers[i] is the high tier; it applies when the request's total input tokens ≥ min_context
  • At most 1 high tier is currently returned

Tier Dimension ​

Threshold matching is based on "total input tokens", including cache and multimodal content: plain text input, text cache (cache_read / cache_create), and image/audio/video input along with their cache reads all count toward the total.

Matching Rules ​

Matching proceeds from large to small: among the tiers satisfying total >= min, the one with the largest threshold is selected, and the entire request is billed at the matched tier's unit price (consistent with official providers — not progressive). If no tier is matched, the base tier applies.

Data Updates & Caching ​

DimensionDescription
Server-side cache60-second in-process cache; model/price changes take effect within at most 1 minute
Client-side cacheResponse includes Cache-Control: public, max-age=60, safe for CDNs and browsers to cache for 1 minute
Recommended crawl frequency≥ once every 5 minutes; high-frequency crawling will be rate-limited

Differences from Other Endpoints ​

EndpointPurposeAuth
/v1/models/pricingThis endpoint: published prices (OpenRouter spec)Public
/v1/modelsOpenAI SDK-compatible model ID listToken required
Console pricing pageFront-end price display (with user context)Login required

FAQ ​

Why are the returned prices different from what I actually pay?

The published price is the final transaction price of the "default group" in anonymous scenarios. If you belong to another group, have tier discounts, or access via a reseller domain, your actual payment will differ. After logging in, please refer to the prices shown on the console pricing page.

Why are some fields "0"?

"0" can mean either "free" or "this dimension is not supported by the model". Please evaluate model capabilities together with supported_features and supported_sampling_parameters — do not infer feature support from pricing fields alone.

How are per-second models (TTS / video) converted?

The OpenRouter specification does not support a per_second field, so the platform converts per-second price × seconds into the published request / video / audio fields using a "typical use-case duration" (30 seconds by default). Actual billing is always real seconds × unit price — nothing is overcharged or undercharged due to the conversion.

Is there a crawl frequency limit?

The endpoint enforces a strict per-IP rate limit. We recommend crawling no more than once every 5 minutes and using the Cache-Control: max-age=60 response header for client-side caching.

Can I filter by vendor / modality?

The endpoint currently does not support filter parameters and always returns all models in normal status. Clients can filter the data array themselves by fields such as supported_features / input_modalities.