Model Listing
List available provider models through Anvia clients.
Provider clients can list models through the normalized listModels() method.
import { OpenAIClient } from "@anvia/openai";
const client = new OpenAIClient({ apiKey });
const models = await client.listModels();
for (const model of models.data) {
console.log(model.id, model.contextLength);
}listModels() returns a ModelList from @anvia/core/model-listing.
type ListedModel = {
id: string;
name?: string;
description?: string;
type?: string;
createdAt?: number;
ownedBy?: string;
contextLength?: number;
};
type ModelList = {
data: ListedModel[];
};Only id is guaranteed. Providers and compatible gateways expose different metadata, so unknown fields remain omitted.
Supported Clients
await new OpenAIClient({ apiKey }).listModels();
await new AnthropicClient({ apiKey }).listModels();
await new GeminiClient({ apiKey }).listModels();
await new MistralClient({ apiKey }).listModels();Each client fetches live provider data. Anvia does not add hidden model metadata, cache the result, or include beta/private model ids that the provider does not return.
Compatible Gateways
OpenAI-compatible gateways use the same OpenAIClient path.
const client = new OpenAIClient({
baseUrl: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
const models = await client.listModels();The request goes to the configured gateway models endpoint, usually GET {baseUrl}/models. If the gateway returns sparse OpenAI-shaped data, Anvia normalizes fields such as id, createdAt, and ownedBy. If the gateway returns richer fields such as name or context_length, Anvia includes those as name and contextLength.
If the gateway does not expose a compatible model-list endpoint, listModels() rejects with ModelListingError.
Manual Model Lists
You do not need listModels() to use a model. If your app already knows the allowed model ids, define a manual ModelList and pass those ids to the provider client.
import type { ModelList } from "@anvia/core/model-listing";
import { OpenAIClient } from "@anvia/openai";
const models: ModelList = {
data: [
{
id: "openai/gpt-5-mini",
name: "GPT-5 Mini",
ownedBy: "openai",
contextLength: 400_000,
},
{
id: "anthropic/claude-sonnet-4.6",
name: "Claude Sonnet 4.6",
ownedBy: "anthropic",
contextLength: 200_000,
},
],
};
const client = new OpenAIClient({
baseUrl: process.env.OPENAI_COMPATIBLE_BASE_URL,
apiKey: process.env.OPENAI_COMPATIBLE_API_KEY,
});
const selectedModelId = models.data[0]?.id ?? "openai/gpt-5-mini";
const model = client.completionModel(selectedModelId);Use this pattern for configuration screens, private deployments, beta models, or gateways that do not expose GET /models.
If you want a manually defined source to match the same shape as provider clients, implement ModelListingClient:
import type { ModelList, ModelListingClient } from "@anvia/core/model-listing";
function staticModelListing(models: ModelList): ModelListingClient {
return {
async listModels() {
return models;
},
};
}You can also merge live provider data with manual entries:
const liveModels = await client.listModels().catch((): ModelList => ({ data: [] }));
const mergedModels: ModelList = {
data: [
...models.data,
...liveModels.data.filter(
(liveModel) => !models.data.some((manualModel) => manualModel.id === liveModel.id),
),
],
};Unlisted Models
You can still use a known beta or private model id directly:
const model = client.completionModel("provider/beta-model");That model will not appear in listModels() unless the provider includes it in the model-list response.
Cookbook
Run the model-listing cookbook example:
pnpm cookbook:providers:10