GET /v1/models is the programmatic way to enumerate the catalog. It returns every model that is currently serving, across all modalities — text, code, reasoning, multimodal, embeddings, image, audio, and video — in OpenAI’s Model shape, with each entry enriched so you can tell what the model accepts, what it costs, and which endpoint to call it through.
It needs a bearer key, but nothing more: discovery is exempt from budget checks, so the call keeps working even when your balance has run out. That is deliberate — deciding what to top up for is exactly the moment you need to read the catalog.
/v1/models is the catalog endpoint, and like every /v1/* route it needs a
key. If you don’t have one yet, start with the
quickstart.Calling /v1/models
{"object": "list", "data": [...]} — so the entries are under .data, not at the top level. Each entry looks like this:
id— the value to pass asmodelin subsequent calls.aliases[]— stable, human-friendly handles for the same model (e.g.coder-30b). Any alias works in place ofid. The field is omitted for models that have no alias. Unlikeid, an alias does not change when the underlying checkpoint or quantization does, so pin config to an alias if you want it to survive model updates.category— the model’s modality/family. This is what tells you which endpoint to call; see Category → endpoint.supported_parameters[]— the request parameters this specific model actually honors. This is the field to gate on: check it before sending a parameter rather than learning the answer from a runtime error.input_modalities[]— what the model accepts. Vision support shows up here asimage, not insupported_parameters, because image input is a message shape rather than a request parameter.context_length/max_output_length— the context window and the maximum completion length, in tokens.pricing— per-token USD rates as decimal strings, on models billed per token. Per-unit models (image, audio, video) have nopricingobject; read their rates fromGET /v1/pricing(see Reading prices below).supported_features[]— what the model can do, as opposed to what you may send. The two fields answer different questions, and the difference is worth holding onto.supported_parametersis the request contract: every entry has honored request behaviour behind it, which makes it the field to gate a request on. Most entries are literal keys you send;structured_outputsis the exception, marking support for a mode of another key (response_format: {"type": "json_schema"}— see Structured outputs) rather than something you send by that name.supported_featuresis a capability description, so it can name an ability with no request key behind it at all. Today it carriesreasoningon models that produce an extended reasoning trace,toolson tool-calling models, andjson_mode(which no model in the catalog currently declares).reasoningappears only here because reasoning is not uniformly controllable: some models reason unconditionally and offer no switch, while the depth dial we do advertise isreasoning_effort, which appears insupported_parameterson the models that accept it. So to find the reasoning models, read this field. Controlling how much they reason is a separate question, andsupported_parametersis where it is answered: a model listingreasoning_effortaccepts that dial, and ifreasoning_effortis absent then/v1/modelsadvertises no reasoning-control parameter for that model. Gate on what is advertised — as everywhere else on this endpoint, a parameter you don’t see listed is one we don’t undertake to honor.
Category → endpoint
A model’scategory tells you which endpoint it’s called through:
For
audio, input_modalities disambiguates the direction: a model whose input_modalities includes audio is speech-to-text; otherwise it’s text-to-speech.
Per-capability discovery flow
Each filter below finds the models, and the endpoint that follows is what you call once you have anid.
Chat & text
POST /v1/chat/completions. See streaming and tool use for the common patterns.
The max_tokens check is the general form of “is this model callable through the chat endpoint”: every chat model advertises the sampling surface, and no other endpoint’s parameter list contains it. Category alone is a weaker signal — it describes what a model is, not which endpoint accepts it — so the two together are what you want whenever you intend to POST the result to /v1/chat/completions.
Tool calling
Gate onsupported_parameters containing tools. If it’s absent, tool calling does not work on that model, whatever your SDK lets you send.
Structured outputs
Strict schema enforcement —response_format: {"type": "json_schema"} — requires structured_outputs. Sending a json_schema request to a model without it is rejected with a 400.
Vision (image input on chat)
select is doing real work: input_modalities says the model accepts an image, which is also true of an image-editing model that you call through /v1/images/generations. Requiring max_tokens narrows it to models that implement the chat sampling surface, so you get only the ones this endpoint is right for.
Call with POST /v1/chat/completions and pass image parts in the content array. The full pattern lives in the vision guide.
Embeddings
POST /v1/embeddings. See the embeddings guide.
Image generation
POST /v1/images/generations. See the image generation guide.
Text-to-speech
Both directions of audio sharecategory: "audio", so the modality arrays are what separate them. A text-to-speech model produces audio:
POST /v1/audio/speech. See the audio guide.
Speech-to-text
A transcription model accepts audio:POST /v1/audio/transcriptions. See the audio guide.
Video generation
POST /v1/videos/generations. See the video generation guide.
Reading prices
pricing.prompt and pricing.completion are per-token USD rates, given as decimal strings so they survive a JSON round-trip without floating-point loss. To get the more familiar per-million-token figure, multiply by a million:
pricing object at all — image generation bills per image, text-to-speech per character, transcription per minute of audio, and video per second, and none of those units has a key in the per-token shape above. Read their rates from GET /v1/pricing, which takes the same bearer key and carries a pricing_type naming the unit:
pricing_type is one of per_token, per_image, per_second, per_character, or per_minute, and unit_price_usd is the rate for that unit. An absent pricing on /v1/models never means free — every model in the catalog bills against your balance.
Retired model ids and the suggested_model hint
Dated ids (a model id ending in a date-style suffix, like
DeepSeek-V4-Flash-0731) are pinned to the exact checkpoint they name: a
dated id is never re-pointed at different weights, so the model behind it
can’t change under you. If you need reproducible behavior, pin a dated id
where one exists. An undated id is the model’s family name and may move
to a newer checkpoint when one replaces the old — when that happens we
announce it, and going forward the replacement ships under a new dated id
while the outgoing id is retired rather than left pointing at weights it no
longer describes.
A request that names a retired — or temporarily unavailable — id fails with
404, and when a direct replacement exists the error body names it in a
stable machine-readable field:
suggested_model is a declared successor — a contract you can act on
programmatically (update your configured model id and retry), unlike
did_you_mean, which is fuzzy spelling help. Prices may differ between a
retired id and its successor; check /v1/models or the
model catalog before switching.
Current cases: DeepSeek-V4-Flash (the family’s 0422 checkpoint) is
retired from the serverless API — requests fail as above with
suggested_model: "DeepSeek-V4-Flash-0731", the serverless offering. The
0422 checkpoint itself is not gone: it may be available as a dedicated
deployment depending on capacity — contact us to
discuss your requirements. The two are distinct checkpoints with distinct
pricing, so treat the switch as a model change, not a rename. Note
that the undated id DeepSeek-V4-Flash may later be re-pointed to the newest
checkpoint in the family — so if it reappears on /v1/models, that does not
mean the 0422 checkpoint returned; check which checkpoint the id names before
switching back. If you need the 0422 checkpoint specifically, use the
contact route above rather than watching /v1/models. The dated
id deepseek-ai/DeepSeek-V4-Flash-0731 announced at the 2026-08 cutover
keeps working unchanged.
See also
- Model catalog — human-readable table of every hosted model, with capabilities and pricing.
- OpenAI compatibility — what’s in and out of
/v1/*, including the scope of/v1/models. - Billing — how per-token pricing maps to charges.