On this page
Core concepts
Models
The catalog is public, prices are per million tokens, and ids are stable bare names.
GET /v1/models returns every public model. The same data powers the model catalog in this site. No authentication is required.
List models
/v1/modelsPublicAliases: /models and /api/v1/models. Private models are excluded.
{ "data": [ { "id": "deepseek-v4.1-flash-1017", "name": "deepseek-v4.1-flash-1017", "created": 1792276400, "description": "DeepSeek V4.1 Flash — 1M token context, up to 384,000 output tokens, text / image input, prompt caching.", "modality": "text,image", "supports_cache": true, "context_length": 1000000, "max_output_tokens": 384000, "is_free": false, "discounted": true, "discount_pct": 20, "saved_pct": 20, "pricing": { "prompt": 0.12, "completion": 0.48, "token_multiplier": 1.0, "fixed_micro": 1000, "image_micro": 0, "audio_min_micro": 0, "video_sec_micro": 0, "official_prompt": 0.15, "official_completion": 0.6, "discount_pct": 20, "discount_fiat_micro": 0, "saved_pct": 20 } } ]}Pricing fields
modalitylists accepted input types, for exampletext,imageortext,image,video.supports_cacheflags prompt caching support.createdis the catalog row's creation time, not the model's release date.- The list is the public catalog price. Per-account overrides are applied at billing time.
discountedis true when the billed price is below the official baseline.discount_pctis the configured discount;saved_pctis the effective saving.
Model detail
/v1/models/{id}PublicReturns the full public record for one model. Aliases: /models/{id} and /api/v1/models/{id}.
{ "id": "deepseek-v4.1-flash-1017:free", "name": "DeepSeek V4.1 Flash 1017 (free)", "created": 1792513342, "updated": 1792513342, "description": "Free tier build of DeepSeek V4.1 Flash (2026-10-17): 700,000 input tokens, 300,000 output tokens, text and image input, prompt caching.", "provider": "inferhub", "modality": "text,image", "supports_cache": true, "context_length": 700000, "max_output_tokens": 300000, "is_free": true, "private": false, "discounted": false, "discount_pct": 0, "saved_pct": 0, "limits": { "input_tokens": 700000, "output_tokens": 300000 }, "pricing": { "prompt": 0, "completion": 0, "token_multiplier": 1, "fixed_micro": 0, "image_micro": 0, "audio_min_micro": 0, "video_sec_micro": 0, "official_prompt": 0, "official_completion": 0, "discount_pct": 0, "discount_fiat_micro": 0, "saved_pct": 0 }}provideris the routing provider id. The upstream model name is never exposed publicly; admins can read it fromGET /admin/models/{id}.limits.input_tokensandlimits.output_tokensmirror the context window and output cap for “limits” blocks.private: truemeans the model is account-scoped. Only callers whose token belongs to an allowed account can see it; everyone else gets404.- Unknown or disabled ids also return
404.
Context limits are enforced
context_length and max_output_tokens are not advisory. A prompt estimate over the context window is rejected with 400, and max_tokens is clamped to the model's output cap when the row defines one.
Free models and daily caps
Free rows (is_free: true) bill $0 and skip the funds gate, but still consume the free-tier quota. Paid rows can also carry per-account daily caps (daily_input_tokens / daily_output_tokens, 0 = unlimited) enforced from UTC midnight.
Check GET /account/limits for today's usage and remaining budget; caps are not part of the public catalog row.
Private models
A model can be private through models.allowed_users, a comma-separated user-id list. Private models never appear in /v1/models; the caller must know the id and be in the list. The public status endpoint counts all enabled models, including private ones, so its models.enabled can be slightly higher than the catalog length.
Discounts
Prices are derived from the official upstream rate and can be discounted per model by percentage and/or a flat amount. Operators set these from the admin panel, which calls:
PATCH /admin/models/{id}{ "discount_pct": 20, "discount_fiat_micro": 1000 }discount_pctis 0–100;discount_fiat_microis ≥ 0.- Sending one value keeps the other. Recomputing overrides manual prices in the same request.
0for both restores the official price.- Discounts are public: every caller sees the same catalog price, minus their own per-account override.
The same values are available from the ops CLI:
./relayctl discount all pct=15./relayctl discount deepseek-v4.1-flash-1017 pct=20 fiat_micro=1000
# our price = official * (1 - pct/100) - fiat_micro/1e6# floor: $0.00001 per 1M tokensofficial_prompt_per_m and official_completion_per_m are stored alongside the billed price, so a discount can be recomputed later. Per-account price_overrides still win over the catalog.
Filtering in your UI
There is no ?capability= filter. Filter client-side on id, context_length, modality, or supports_cache. Tool and JSON-mode flags are not exposed; keep a static map in your frontend if you need capability badges.
Account-aware catalog