Call Multiple LLMs
Through One Production API
Call GPT, Claude, Gemini, and other models through one production API while preserving capability, routing, security, cost, and trace evidence.
Published: March 19, 2026 · By the QVeris Team
TL;DR
Applications share authentication, request envelopes, tracing and operational controls.
GPT, Claude and Gemini differ by model, endpoint, version, tools, context, modalities and policy.
Resolve a workload alias only to endpoints that satisfy required behavior.
Return provider and model identity, request IDs, usage, route and transformations with normalized output.
What the unified call should standardize
Standardize application concerns that are genuinely common: service identity, tenant, trace context, workload alias, messages, timeout, budget, required capabilities and a stable response envelope. Resolve the alias from a versioned catalog before provider translation.
Do not force every feature into the common denominator. Use typed extensions for provider-specific tools, reasoning, schema, media or caching controls. Reject missing required capabilities before the call rather than silently degrading them.
One-API integration layers
| Layer | Best fit | Verify before choosing |
|---|---|---|
| Canonical request | One SDK sends identity, messages, workload alias and required capabilities. | Keep timeout, budget, trace and tenant explicit; avoid provider assumptions in app code. |
| Capability catalog | Model aliases map to eligible versions and endpoints. | Source and refresh tools, schemas, context, modalities, region, policy and lifecycle. |
| Router | Filters and chooses among eligible GPT, Claude or Gemini endpoints. | Record candidate set, exclusions, policy, route and fallback conditions. |
| Provider adapters | Translate canonical fields to supported native semantics. | Contract-test tools, streams, structured output, errors and usage for each adapter. |
| Response envelope | Applications receive stable fields plus native evidence. | Preserve provider, model, request ID, route, attempts, usage units and transformations. |
Build the common contract around workloads
Name the task contract, not a vendor model, when portability is required.
Declare tools, schema, modalities, context, streaming, region and policy as hard flags.
Allow opt-in native features without pretending every provider supports them.
Keep canonical and native identity together for debugging, cost and audit.
Prove each model path
- Create golden requests for each production workload and required capability combination.
- Run contract tests against every eligible GPT, Claude and Gemini endpoint.
- Diff outputs, tools, streams, errors, usage and latency under real payloads.
- Canary route changes and block on workload-specific invariant regressions.
- Keep provider-native direct paths for diagnosis and tested rollback.
Use aliases above typed provider adapters
The application sends a canonical request with workload alias and required capabilities. A catalog expands eligible endpoints; a policy router selects one; a typed adapter maps the request. The normalized response returns with provider-native identity and evidence. Unsupported requirements fail before execution, and fallback uses only verified equivalents.
Production rule: one client contract must not become one vague promise that every model behaves the same.
Design the canonical request contract first
Start with the behavior your application needs, not with one provider's JSON. A useful request includes a workload alias, ordered messages, required capabilities, optional preferences, timeout, maximum spend, tenant, trace context, and an idempotency key where retries can create side effects. Keep hard requirements separate from preferences: JSON schema compliance may be required, while lower latency may only be a preference.
The response should be equally deliberate. Return normalized content and tool calls, then attach the selected provider, exact model version, gateway request ID, upstream request ID, routing policy, attempt count, usage units, finish reason, and any lossy transformation. That envelope gives application code stability without erasing the evidence needed for debugging.
Filter by capability before optimizing the route
Build a versioned capability catalog for every allowed model endpoint. Record supported input modalities, tool calling, parallel tools, structured output, streaming, context limits, regions, data handling, lifecycle status, and known workload quality. Refresh the catalog from official documentation and verified probes; do not let a marketing model name stand in for an executable capability claim.
Routing is a two-stage decision. First remove candidates that fail a hard requirement. Only then rank the eligible set by quality, latency, availability, price, residency, or tenant policy. Record both the candidate set and exclusion reasons so “smart routing” remains explainable when a result or bill is challenged.
Keep provider translation inside typed adapters
Each adapter owns translation to and from one native API: message roles, system instructions, tools, schemas, media, sampling controls, stop reasons, error types, rate-limit headers, and usage. The adapter must reject an impossible mapping. Silently dropping a schema, tool choice, image, or safety option creates a successful HTTP response with the wrong behavior.
Avoid a lowest-common-denominator API. Keep a compact portable core and expose namespaced, typed extensions for features that are intentionally provider-specific. The caller then knows whether it requested portable behavior or accepted a lock-in boundary.
Treat streams, tools, and structured output as protocols
A stream is more than text chunks. Providers can emit content deltas, reasoning events, tool arguments, citations, usage, and terminal metadata in different orders. Define a gateway event model, test chunk assembly and cancellation, and preserve the native terminal reason. Once bytes have reached the caller, automatic fallback can duplicate text or produce a mixed answer.
Tool calling also needs a lifecycle: validate arguments, authorize the tool, attach a stable call ID, record the result, and decide who resumes the model. For structured output, test the exact schema constructs each route supports and validate the final payload again at the gateway boundary.
Use one client key without flattening upstream secrets
Applications should authenticate to the gateway with a scoped credential tied to service, tenant, environment, and allowed workloads. Provider keys stay encrypted behind the gateway. Give each secret an owner, environment, provider account, rotation schedule, allowed routes, and emergency revocation path. A single leaked client token should not reveal or unlock every upstream account.
Enforce per-tenant quotas, concurrency, model allowlists, and spend limits at the gateway. Redact prompts and credentials from logs by default, and make any payload retention an explicit policy rather than an observability side effect.
Make fallback narrow, bounded, and observable
Retry transient failures with capped exponential backoff and jitter, while respecting provider retry guidance. Fallback may select only a prequalified equivalent for the same workload. Carry the original deadline and budget across attempts; do not give every retry a fresh allowance. Stop on authentication, invalid requests, policy rejections, and unsupported features.
Never blindly replay a request after a partial stream or a side-effecting tool call. Use idempotency keys, tool execution ledgers, and explicit resume rules where recovery is necessary. Return the attempt history so operators can distinguish a slow first route from a successful but expensive fallback chain.
Measure accepted work, not just token price
Normalize usage into a cost record without pretending provider units are identical. Store native input, output, cached, reasoning, image, audio, and tool-related units alongside the provider's billed amount and currency. Join that record to workload, tenant, route, latency, retries, quality score, and acceptance outcome.
The useful comparison is cost per accepted task, not the advertised price per token. Track success rate, p50 and p95 latency, schema-valid rate, tool success, fallback rate, budget overruns, and quality by alias. Alerts should include the gateway request ID, chosen path, policy version, and upstream evidence.
Production checklist for one multi-LLM API
- Version the request, response, aliases, capability catalog, and routing policy independently.
- Fail before execution when no route satisfies every hard capability and policy requirement.
- Contract-test every adapter for text, streams, tools, schemas, errors, cancellation, and usage.
- Keep upstream secrets isolated; scope client credentials and budgets by tenant and workload.
- Canary alias changes, compare golden workloads, and retain a tested rollback path.
- Expose selected provider, exact model, transformations, attempts, native IDs, usage, and cost.
Seven mistakes that make a unified API unsafe
| Mistake | Production consequence | Better control |
|---|---|---|
| Lowest-common-denominator contract | Important features disappear silently. | Portable core plus typed extensions. |
| Opaque smart routing | Quality and cost changes cannot be explained. | Log candidates, exclusions, policy, and route. |
| Hidden provider identity | Incidents and invoices cannot be reconciled. | Return exact native identity and request IDs. |
| Unlimited retry chains | One request multiplies latency and spend. | Shared deadline, shared budget, capped attempts. |
| Stale model catalog | Aliases point to retired or changed behavior. | Official sources, probes, owners, and expiry. |
| Semantic fallback | Availability rises while answer quality falls. | Prequalify alternates per workload. |
| Shared upstream keys | Leaks gain broad provider access. | Scoped client auth and isolated secrets. |
One model API plus one capability interface
The unified model API gives an agent consistent inference access. QVeris gives that agent Discover → Inspect → Call access to external APIs, tools, services and live data. Stack them as model interface plus capability interface, sharing workload identity and trace context.
Keep one request shape and explicit model aliases
A unified endpoint is useful only when callers can predict what each alias means. Use product-owned aliases, return the native provider and exact model in the response metadata, and reject unknown aliases instead of silently choosing a default.
for alias in support-fast support-quality; do
curl --fail-with-body "$LLM_GATEWAY_BASE_URL/chat/completions" -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" -H "Content-Type: application/json" -H "X-Workload: support-answer" -d "{"model":"$alias","messages":[{"role":"user","content":"Reply $alias OK"}]}"
done
- Document each alias's capability, quality gate, region, lifecycle, and owner.
- Require response metadata to expose chosen provider, native model, policy version, and usage.
- Run the same golden workload against every alias before changing its mapping.
Verified implementation reference: OpenAI Chat Completions reference.
Continue with related implementation guides
Use these adjacent guides to compare the next architectural decision, implementation boundary, or operating control without starting the research again.
FAQ
Yes. A gateway can expose one client endpoint and translate a canonical request into each native API. Capability checks still matter because tools, schemas, streams, modalities, limits, and errors differ.
Yes. Applications may use stable workload aliases, but response metadata should preserve the selected provider, exact model, policy version, request IDs, usage, and transformations.
Only when the alternate passes the workload's capability, policy, region, and quality contract. Never replay partial streams or side-effecting tool calls without a safe idempotency design.
No. Applications use a scoped gateway credential. Provider keys remain encrypted upstream secrets with separate ownership, rotation, quotas, and audit records.
Normalize identity, messages, aliases, timeouts, budgets, required capabilities, trace context, common output fields, and error classes. Keep typed extensions and native evidence where behavior is not equivalent.
Run versioned golden workloads and adapter contract tests across every eligible route. Compare tools, schemas, streams, errors, usage, latency, safety behavior, and task quality.
