← Back to research
Guides9 min readPublished 2026-07-20

How to List Models from an OpenAI-Compatible API

List models from an OpenAI-compatible API with Python or curl, verify exact IDs, build a safe allowlist, and avoid stale model-name failures in production.

By LumeAPI Engineering Team

OpenAI-Compatible API hub →

Last verified: July 20, 2026

Call GET /v1/models or client.models.list() to discover exact model IDs from an OpenAI-compatible API before sending a generation request. With LumeAPI, configure the client base URL as https://api.lumeapi.site/v1 and authenticate with the same LumeAPI key used for chat. The live models route correctly rejected an unauthenticated request with 401 on July 20, 2026.

Do not guess an ID from a marketing name. Claude Sonnet 4.6 is a display label; claude-sonnet-4-6 is the current LumeAPI catalog ID. A single character difference can produce a model-not-found or allowlist error.

List models with curl

bash
curl https://api.lumeapi.site/v1/models \
  -H "Authorization: Bearer $LUMEAPI_KEY"

A conventional response has object: "list" and a data array containing model objects. The most important field for a caller is data[].id. Other fields such as created or owned_by may be present, but portable application code should not require optional metadata unless the gateway documents it.

Never paste a production key directly into shared shell history. Load it from a secret manager or environment variable.

List models with the OpenAI Python SDK

bash
python -m pip install --upgrade openai
export LUMEAPI_KEY='your-lumeapi-key'
python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ['LUMEAPI_KEY'],
    base_url='https://api.lumeapi.site/v1',
    timeout=20.0,
)

page = client.models.list()
for model in sorted(page.data, key=lambda item: item.id):
    print(model.id)

This reuses the official client while sending the request to the configured compatible endpoint. If no custom base_url is supplied, the SDK will contact its default host instead.

Filter for the model families you use

A gateway catalog may include text, image and video models. Filter IDs for display, but keep the complete response available for validation.

python
def group_model_ids(ids: set[str]) -> dict[str, list[str]]:
    groups = {'gpt': [], 'claude': [], 'gemini': [], 'other': []}
    for model_id in sorted(ids):
        if model_id.startswith('gpt-'):
            groups['gpt'].append(model_id)
        elif model_id.startswith('claude-'):
            groups['claude'].append(model_id)
        elif 'gemini' in model_id:
            groups['gemini'].append(model_id)
        else:
            groups['other'].append(model_id)
    return groups

ids = {item.id for item in client.models.list().data}
for family, model_ids in group_model_ids(ids).items():
    print(f'{family}: {len(model_ids)}')
    for model_id in model_ids:
        print(f'  {model_id}')

Prefix grouping is an application convenience, not an API guarantee. A namespaced ID such as provider/model-name may belong in a family even when it does not start with that family name. The public LumeAPI model catalog provides human-readable series and pricing context.

Validate configured IDs at startup

Fail fast when a deployment references a removed, misspelled or unavailable ID.

python
REQUIRED_MODELS = {
    'gpt-5.4-mini',
    'claude-sonnet-4-6',
    'gemini-3.5-flash',
}

def validate_required_models() -> None:
    available = {item.id for item in client.models.list().data}
    missing = REQUIRED_MODELS - available
    if missing:
        joined = ', '.join(sorted(missing))
        raise RuntimeError(f'Configured model IDs unavailable: {joined}')

validate_required_models()

Whether startup should fail depends on the service. A worker dedicated to one model should usually stop. A multi-model service may remain healthy if it disables only the affected route and has a tested alternative.

Separate discovery from authorization policy

Do not let end users send an arbitrary ID simply because it appeared in /models. Maintain a smaller server-side allowlist tied to tasks, budgets and tests.

python
TASK_MODELS = {
    'ticket_classification': 'gpt-5.4-mini',
    'careful_review': 'claude-sonnet-4-6',
    'interactive_reply': 'gemini-3.5-flash',
}

def model_for_task(task: str, available: set[str]) -> str:
    try:
        selected = TASK_MODELS[task]
    except KeyError as exc:
        raise ValueError(f'Unknown task: {task}') from exc
    if selected not in available:
        raise RuntimeError(f'Model unavailable for {task}: {selected}')
    return selected

This prevents a user-controlled model parameter from selecting an untested or unexpectedly costly model. LumeAPI also enforces catalog model allowlists at the gateway; your application allowlist is an additional business-policy layer.

Cache carefully

Model discovery is useful at deploy time, in health checks and in an admin screen. It usually does not belong on every generation request.

A practical policy is:

  • Fetch at startup and refresh on a timer such as every 15–60 minutes.
  • Preserve the last successful set during a temporary discovery failure.
  • Alert when a required ID disappears.
  • Require a deliberate configuration change before routing production traffic to a newly appeared ID.
  • Record the retrieval time and base URL with the cached set.

Do not treat cache presence as proof the model is healthy. A model can remain listed while requests are throttled or degraded. Use request metrics and a bounded LLM fallback policy separately.

Why lists differ between endpoints or keys

Two OpenAI-compatible model lists can differ for legitimate reasons:

  1. The gateways support different upstream catalogs.
  2. A key is scoped to a model allowlist, region or account plan.
  3. Preview models were added, renamed or removed.
  4. The public catalog and authenticated API refresh at different times.
  5. One endpoint returns only models usable by the current key.

Compare the exact base URL and key before concluding the API is broken. Log a fingerprint of the base URL, not the secret, and record the count plus required IDs.

Use current LumeAPI IDs and dated prices

Examples verified in the LumeAPI catalog on July 20, 2026 include:

FamilyModel IDLumeAPI input/output per 1M tokensDisplayed reference
GPTgpt-5.4-mini$0.225 / $1.35$0.75 / $4.50
Claudeclaude-sonnet-4-6$1.80 / $9.00$3.00 / $15.00
Geminigemini-3.5-flash$0.90 / $5.40$1.50 / $9.00

The GPT example is 70% below its displayed reference, while the Claude and Gemini examples are 40% lower. “Up to 70%” does not mean every model has that discount. Rates and IDs can change; verify the live AI API pricing and model documentation before a purchasing decision.

What /v1/models does not prove

A listed ID does not by itself prove:

  • that your prompt regression tests pass;
  • that tool calling or strict JSON Schema is supported;
  • that latency meets your target;
  • that context limits match another provider;
  • that the model is currently free of throttling;
  • that every modality uses /chat/completions.

After discovery, run the OpenAI-compatible endpoint test and model-specific feature tests. Image and video models share the LumeAPI account and wallet but can use different endpoints and asynchronous flows.

A production model-discovery checklist

  • Use the intended custom base URL.
  • Authenticate without logging the key.
  • Extract exact IDs rather than display labels.
  • Compare required IDs with the authenticated response.
  • Keep a smaller application allowlist.
  • Cache the list with a timestamp.
  • Alert on removed required models.
  • Test features and quality separately.
  • Link operators to the current model docs and pricing.

With LumeAPI, one key can discover and call supported GPT, Claude and Gemini IDs, while one USD wallet and console consolidate usage. That makes model inventory easier to operate without pretending all models have identical behavior.

Sources and limitations

All Python blocks were syntax-checked on July 20, 2026. The authenticated response can depend on the key, and no customer inference key was used to enumerate or call the complete account catalog for this article.