You can access 500+ AI models through one API key by using an AI API gateway with an OpenAI-compatible endpoint. Your application keeps one client, one authentication flow, and one request format; changing models becomes a configuration change. You still need to test each model's capabilities, limits, latency, and output behavior before production use.
Why I wanted one integration instead of 12 SDKs
Most AI applications do not stay on one model forever. A team may use one model for code, another for low-cost classification, and a third for image or video generation. Direct integrations can quickly turn into a maintenance problem:
- credentials live in different systems;
- request and response formats vary;
- model names get scattered through the codebase;
- retry, timeout, and logging logic is duplicated;
- switching providers requires application changes.
An API gateway does not make every model identical. It gives the application a stable entry point and a shared authentication layer. Model-specific features still need model-specific testing.
For this walkthrough, I use CometAPI, which currently advertises access to 500+ models through one API key and an OpenAI-compatible API.
What actually stays the same?
| Integration concern | Without a shared gateway | With a shared gateway |
|---|---|---|
| API key | One or more per provider | One application secret |
| Base URL | Different for each provider | One base URL |
| Client setup | Multiple SDKs or adapters | One OpenAI-compatible client |
| Model selection | Often tied to provider code | A configuration value |
| Observability | Separate logs and dashboards | A shared request path |
| Model behavior | Varies by model | Still varies by model |
The last row matters: a common API schema reduces integration work, but it does not erase differences in context windows, tool calling, structured output, safety behavior, or multimodal support.
Prerequisites
- Python 3.10 or later
- A CometAPI API key
- A current model ID copied from the CometAPI model catalog or documentation
Install the official OpenAI Python client:
python -m pip install --upgrade openai
Store credentials in environment variables. Never paste a real API key into source code or a Git repository.
export COMETAPI_API_KEY="your_api_key_here"
export COMETAPI_MODEL_ID="copy_a_current_model_id_from_the_catalog"
Make the first request
Create quickstart.py:
import os
from openai import OpenAI
api_key = os.environ.get("COMETAPI_API_KEY")
model_id = os.environ.get("COMETAPI_MODEL_ID")
if not api_key:
raise RuntimeError("Set COMETAPI_API_KEY before running this script.")
if not model_id:
raise RuntimeError("Set COMETAPI_MODEL_ID to a current catalog model ID.")
client = OpenAI(
api_key=api_key,
base_url="https://api.cometapi.com/v1",
timeout=60.0,
max_retries=2,
)
response = client.chat.completions.create(
model=model_id,
messages=[
{
"role": "system",
"content": "You are a concise senior Python reviewer.",
},
{
"role": "user",
"content": (
"Review this function and return three concrete improvements:\n"
"def total(xs):\n"
" value = 0\n"
" for x in xs:\n"
" value += x\n"
" return value"
),
},
],
temperature=0.2,
)
print(response.choices[0].message.content)
if response.usage:
print(
f"tokens: input={response.usage.prompt_tokens}, "
f"output={response.usage.completion_tokens}"
)
Run it:
python quickstart.py
The important part is not the prompt. It is that the base URL and client stay fixed while COMETAPI_MODEL_ID is configuration.
Switch models without changing application code
Suppose a staging test needs to compare three current catalog models. Put their exact IDs in a comma-separated environment variable:
export COMETAPI_MODEL_IDS="model_id_a,model_id_b,model_id_c"
Then run the same task against each model:
import os
import time
from openai import OpenAI
api_key = os.environ.get("COMETAPI_API_KEY")
raw_model_ids = os.environ.get("COMETAPI_MODEL_IDS", "")
model_ids = [item.strip() for item in raw_model_ids.split(",") if item.strip()]
if not api_key:
raise RuntimeError("Set COMETAPI_API_KEY.")
if not model_ids:
raise RuntimeError("Set COMETAPI_MODEL_IDS to one or more current model IDs.")
client = OpenAI(
api_key=api_key,
base_url="https://api.cometapi.com/v1",
timeout=60.0,
max_retries=2,
)
prompt = "Return JSON with keys summary and risk for a password-reset email."
for model_id in model_ids:
started = time.perf_counter()
try:
response = client.chat.completions.create(
model=model_id,
messages=[{"role": "user", "content": prompt}],
temperature=0,
)
elapsed = time.perf_counter() - started
output = response.choices[0].message.content or ""
print(f"\n[{model_id}] {elapsed:.2f}s")
print(output)
except Exception as exc:
elapsed = time.perf_counter() - started
print(f"\n[{model_id}] failed after {elapsed:.2f}s: {type(exc).__name__}")
This is a smoke test, not a benchmark. Run multiple randomized trials before drawing conclusions about latency or quality.
A safer production pattern
Do not let route handlers choose arbitrary model IDs. Put approved models in a small policy layer:
MODEL_POLICY = {
"fast": os.environ["FAST_MODEL_ID"],
"quality": os.environ["QUALITY_MODEL_ID"],
"fallback": os.environ["FALLBACK_MODEL_ID"],
}
def choose_model(task_class: str) -> str:
try:
return MODEL_POLICY[task_class]
except KeyError as exc:
raise ValueError(f"Unsupported task class: {task_class}") from exc
This keeps product logic independent from vendor naming and gives your team one place to change routing decisions.
What to test before adding a model
Use the same acceptance suite for every candidate:
- Capability: Does the model support the endpoint and features you use?
- Quality: What is its pass rate on 30–100 representative tasks?
- Latency: What are median and P95 response times under realistic load?
- Reliability: How often do requests time out, return invalid data, or require a retry?
- Cost: What is the cost per accepted result, not merely the list price per token?
- Limits: Are context, output, rate, and regional limits compatible with the application?
- Data handling: Does the route meet your privacy and retention requirements?
Common mistakes
- Hard-coding the API key or model ID in a public example
- Assuming all models support identical request parameters
- Moving to a new model after a single impressive prompt
- Comparing prices without separating input and output tokens
- Treating HTTP success as task success
- Omitting timeouts, retry limits, logging, and a fallback path
Key takeaways
- One OpenAI-compatible client can remove a large amount of provider-specific integration code.
- The model ID should be configuration, not application logic.
- One schema does not mean identical capabilities or behavior.
- A model should pass your own quality, latency, reliability, and cost gates before production.
- Secrets belong in environment variables or a secrets manager.
Top comments (0)