---
title: "List Base Models"
method: GET
path: "/base-models"
tags: ["model-selection"]
---

# List Base Models

`GET /base-models`

Public model catalog — single source of truth for available models.

Returns the union of all provider catalogs. Each model carries
``supports_training`` and ``supports_inference`` flags derived from
``catalog_registry``. Use query parameters to filter by capability.

The ``supports_inference`` flag and filter use
:func:`supports_inference_runtime`, which unions
``supports_base_inference`` across every provider entry **whose
runtime configuration is present in the current process**. A
finetune-only Fireworks decoder still reports ``True`` when it is
bridged through OpenRouter or AWS Bedrock; an Azure-only catalog
slug (``claude-sonnet-4-5``) reports ``True`` only when the brain
has the Azure env vars set so the request actually has somewhere
to go.

Authentication is **optional**. Anonymous callers receive the public
catalog with all feature-flag-gated entries hidden (their flags
resolve to ``default_value=False``). Authenticated callers populate
the request-scoped identity ContextVars via ``FlexibleAuth`` so
per-user / per-team / per-email Datadog Remote Config rules can match,
exposing gated entries (e.g. Gliner-PII, Gliner Guardrails) to users
on a rollout. Bad credentials are silently downgraded to anonymous so
this endpoint never returns 401.

Callers in restricted jurisdictions have the matching families hidden from
the catalog, mirroring the inference-time 451 so the UI never offers an
unusable model: sanctioned regions hide foreign frontier families
(OpenAI/Anthropic/Gemini/Llama) and GDPR regions hide GDPR-restricted
families (Sakana). The jurisdiction is resolved from both CloudFront's
``CloudFront-Viewer-Country`` header and the team's verified billing-card
country, so a VPN cannot unhide a model the caller's card jurisdiction bars.

Examples:
    GET /base-models                          — full catalog
    GET /base-models?supports_inference=true   — serverless-capable models
    GET /base-models?supports_training=true    — trainable models
    GET /base-models?task_type=encoder          — encoder/NER models only
    GET /base-models?task_type=decoder          — decoder/LLM models only
    GET /base-models?task_type=embedding        — text embedding models only

## Query parameters

- `supports_training` boolean, nullable — Filter to models that support fine-tuning
- `supports_inference` boolean, nullable — Filter to models with serverless inference
- `task_type` string, nullable — Filter by model architecture: 'encoder' (NER/GLiNER), 'decoder' (LLM), or 'embedding' (text embedding)

## Response `200`

Successful Response

- BaseModelsResponse — Response listing all base models in the public catalog.
  - `models` BaseModelResponse[], required
    - `id` string, required — Model ID (canonical routing key)
    - `label` string, required — Human-friendly display name
    - `description` string, required — Short description shown in UI
    - `task_type` string, required — Model architecture: 'decoder' for LLMs, 'encoder' for GLiNER/NER models, or 'embedding' for text embedding models
    - `context_window` integer, nullable — Maximum context length in tokens (min across providers)
    - `max_input_tokens` integer, nullable — Maximum input tokens advertised for this model. Matches the conservative provider context window used by this catalog row.
    - `max_output_tokens` integer, nullable — Maximum output tokens advertised for decoder generation. Null when no provider publishes a separate output cap.
    - `release_month` string, nullable — Official release month shown in the public catalog, formatted as 'Mon YYYY' (for example, 'Apr 2026'). Null when unknown.
    - `input_price_per_million` number, nullable — Upper-bound USD list price per million input tokens (highest provider COGS multiplied by the inference margin). Caps what BillableEvent.record can charge for model_inference; actual charges may be lower when the request is routed to a cheaper provider.
    - `output_price_per_million` number, nullable — Upper-bound USD list price per million output tokens (highest provider COGS multiplied by the inference margin). Caps what BillableEvent.record can charge for model_inference; actual charges may be lower when the request is routed to a cheaper provider.
    - `cache_read_price_per_million` number, nullable — Effective upper-bound USD list price per million input tokens served from the provider's prompt cache (Anthropic cache_read_input_tokens, Bedrock cacheReadInputTokens, OpenAI / Fireworks prompt_tokens_details.cached_tokens). Always the rate BillableEvent.record actually charges: when a provider does not differentiate cache-read pricing this equals ``input_price_per_million`` rather than ``None``, so customers compute ``cache_read_tokens × cache_read_price`` without special-casing. ``None`` only when the model has no pricing at all (cache reads are still tracked for analytics).
    - `cache_write_price_per_million` number, nullable — Effective upper-bound USD list price per million input tokens written into the provider's prompt cache (Anthropic cache_creation_input_tokens, Bedrock cacheWriteInputTokens). Providers that charge cache writes at the plain input rate (OpenAI, Modal) report ``input_price_per_million`` here rather than ``None``, matching what BillableEvent.record charges. ``None`` only when the model has no pricing at all.
    - `supports_inference` boolean, required — Whether this model supports serverless base-model inference (pre-deployed, no startup latency, pay-per-token).
    - `is_chat_model` boolean, required — Whether the model has a chat template suitable for /v1/chat/completions. Pretrained/base models lack a chat template and produce gibberish on chat-formatted messages; frontends should route them to /v1/completions instead.
    - `supports_on_demand_inference` boolean, required — Whether this model supports on-demand LoRA deployment (dedicated GPU serving a fine-tuned adapter).
    - `supports_image_input` boolean — Whether this model accepts image (vision) content blocks on the compat inference APIs. True when any provider catalog entry for this model sets supports_vision=True. Output is always text — no model supports image output.
    - `supports_zdr` boolean — Whether this model has a Zero-Data-Retention-compliant route. Informational — shown on the models page. Fails closed: defaults False and is True only when the model is explicitly catalogued as ZDR-supported, so the claim is never over-reported.
    - `supports_training` boolean, required — Whether this model supports fine-tuning on any provider. When False the model is available for inference only.
    - `default_training_batch_size` integer, nullable — Catalog default training batch size for this model. Null when the model is not trainable on a provider that publishes batch defaults. Clients creating training jobs should prefer this value (or omit ``batch_size``) over hard-coding a global default.
    - `max_training_batch_size` integer, nullable — Safe maximum training batch size for this model on the training provider. Null when unset or the model is not trainable. Requests above this maximum are rejected (except the legacy explicit Field-default clamp documented on TrainingJobCreate).
    - `license` string, nullable — SPDX license identifier or short name for the model weights (e.g. 'Apache-2.0', 'Llama-3-Community', 'Proprietary'). Display string only — null when unknown.
    - `tier` string, nullable — Capability tier: 'open' (open weights), 'fast' (latency-optimized), 'enterprise' (proprietary commercial API), or 'research' (research preview). Null when unclassified.
    - `deprecated` boolean — Whether the model is deprecated and discouraged for new work. Deprecated models still serve requests until their sunset date; sunset (removed) models are omitted from this catalog entirely.
    - `replacement_model` string, nullable — Canonical ID of the successor model to migrate to, when the model is deprecated and a replacement is declared.
    - `deprecation_date` string, date, nullable — Date the model entered (or will enter) the deprecated state. Null when the model is not on a deprecation path.
    - `sunset_date` string, date, nullable — Date the model is removed and requests begin to be rejected. Null when no removal is scheduled.
    - `coding_benchmark_mean` number, nullable — Mean of the model's curated coding benchmarks on a 0-100 scale. Null when the model publishes fewer than two of them, since one benchmark is a data point rather than an average.
    - `agentic_benchmark_mean` number, nullable — Mean of the model's curated agentic benchmarks on a 0-100 scale. Null when the model publishes fewer than two of them.
    - `coding_benchmarks` BenchmarkComponentScore[] — The figures averaged into coding_benchmark_mean, strongest first, so a listing can show its working without a request per model. Empty when there is no mean to explain. See GET /base-models/{id}/benchmarks for provenance and ranks.
      - `benchmark_id` string, required — Upstream benchmark slug
      - `label` string, required — Display name for the benchmark
      - `score` number, required — Normalized score on a 0-100 scale
    - `agentic_benchmarks` BenchmarkComponentScore[] — The figures averaged into agentic_benchmark_mean, strongest first.
      - `benchmark_id` string, required — Upstream benchmark slug
      - `label` string, required — Display name for the benchmark
      - `score` number, required — Normalized score on a 0-100 scale
    - `market_input_price_per_million` number, nullable — Median USD per 1M input tokens across the third-party providers serving this model, for comparison against our own rate. Median rather than mean so one outlying listing cannot move it. Never used to bill. Null when nobody publishes a rate for it.
    - `market_output_price_per_million` number, nullable — Median USD per 1M output tokens across third-party providers.
    - `market_price_provider_count` integer, nullable — Provider count behind the better-evidenced side: the larger of the input and output counts, which is a lower bound on how many providers list the model rather than a distinct count of them. The two sides can be drawn from different subsets, since a few providers publish an input rate only, so neither side alone is the total. Present so a lone quote can be told apart from a real market. Null when there are no market rates.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/pioneer/apis/brain-api.md) · [All operations](https://skmtc.net/pioneer/apis/brain-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/pioneer/brain-api/revisions/31dfe831e079/schema)
