The Vercel AI SDK model ID naming gateway vs native is the difference between the model identifier string you pass to the SDK when routing requests through a unified LLM gateway and the identifier required when calling a provider’s API directly. Gateways often present a single OpenAI-compatible surface, but each gateway defines its own convention for addressing models that may or may not match the provider’s native slug.
What the distinction actually means
In the Vercel AI SDK, a “model ID” is the string argument you hand to a provider factory:
import { openai } from '@ai-sdk/openai';
const model = openai('gpt-4o');
When you call OpenAI natively, gpt-4o is the native model ID. The SDK sends it as "model": "gpt-4o" in the JSON body to api.openai.com/v1/chat/completions.
When you point that same factory at a gateway by overriding baseURL, the gateway receives "model": "gpt-4o". Whether that string is valid depends on the gateway’s naming scheme. Some gateways accept native IDs and route internally; others require a prefixed or namespaced ID like openai/gpt-4o or openai:gpt-4o.
The Vercel AI SDK model ID naming gateway vs native question is therefore about contract compatibility: does the gateway’s expected model identifier equal the provider’s native identifier, or does it diverge?
How the Vercel AI SDK resolves model IDs
Provider adapters vs custom base URL
The SDK ships first-party adapters (@ai-sdk/openai, @ai-sdk/anthropic, etc.). Each adapter constructs requests shaped for that provider’s native API. If you set baseURL on the adapter, the SDK still uses the same request shape and model ID formatting—it just changes the host.
const gatewayModel = openai('gpt-4o', {
baseURL: 'https://gateway.example/v1'
});
Here, the SDK sends an OpenAI-style request. The model ID remains gpt-4o. If the gateway expects openai/gpt-4o, you must change the string:
const gatewayModel = openai('openai/gpt-4o', {
baseURL: 'https://gateway.example/v1'
});
Gateway passthrough behavior
A well-designed gateway parses the model field and maps it to a backend. Some gateways treat the field as opaque and require their own catalog slug. Others implement a compatibility layer that strips known provider prefixes and forwards the native ID to the upstream.
For example, a gateway might accept both:
{ "model": "gpt-4o", "messages": [] }
and
{ "model": "openai/gpt-4o", "messages": [] }
but route them identically. Another gateway might reject the unprefixed form with 404 model not found.
Why the naming mismatch causes real bugs
Request shaping and auth
If you hardcode anthropic/claude-3-5-sonnet in the SDK but use the @ai-sdk/anthropic adapter, the SDK may try to send Anthropic-specific headers and body fields. The gateway receives a request it can’t interpret because the adapter and the model string disagree on provider context.
A correct gateway setup either:
- uses the native adapter with native model ID and lets the gateway forward, or
- uses a generic OpenAI-compatible client with gateway namespaced IDs.
Cache keys and routing directives
Model ID strings often become part of cache keys and routing logic. If your gateway honors client routing directives (e.g., x-routing: prefer=anthropic), a mismatched ID can bypass cache or trigger unnecessary fallbacks.
A gateway like n4n.ai exposes one OpenAI-compatible endpoint that addresses 240+ models and honors client routing directives, so you can pass gpt-4o natively and the gateway forwards provider cache-control hints without rewriting your SDK code.
Concrete example: native vs gateway configuration
Native OpenAI call
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const { text } = await generateText({
model: openai('gpt-4o'),
prompt: 'Explain TCP fast open.'
});
Request sent:
POST https://api.openai.com/v1/chat/completions
{ "model": "gpt-4o", "messages": [{"role":"user","content":"Explain TCP fast open."}] }
Gateway call with namespaced ID
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const { text } = await generateText({
model: openai('openai/gpt-4o', {
baseURL: 'https://gateway.example/v1',
apiKey: process.env.GATEWAY_KEY
}),
prompt: 'Explain TCP fast open.'
});
Request sent:
POST https://gateway.example/v1/chat/completions
{ "model": "openai/gpt-4o", "messages": [{"role":"user","content":"Explain TCP fast open."}] }
Gateway call with native ID passthrough
If the gateway supports native passthrough, you keep the exact native code and only swap baseURL:
const { text } = await generateText({
model: openai('gpt-4o', {
baseURL: 'https://gateway.example/v1'
}),
prompt: 'Explain TCP fast open.'
});
This is the cleanest migration path, but it requires the gateway to maintain a native-compatible model catalog.
Common misconceptions
“Gateways always rewrite IDs”
False. Many gateways are transparent proxies that forward the model field verbatim to the upstream provider. They rely on you to send the correct native ID. Others maintain a unified namespace and reject native IDs. Assume nothing; read the gateway’s model list.
“You must use provider-prefixed strings”
Only if the gateway’s routing requires it. The Vercel AI SDK does not enforce prefixes; it passes whatever string you give. If you use the @ai-sdk/openai adapter, the gateway sees an OpenAI-shaped request, so a prefix like anthropic/ may confuse the gateway’s backend selection.
“Model ID is cosmetic”
It is not. The ID determines which weights serve the request, which price tier applies, and whether a cached prefix is reused. A typo’d ID fails loudly at most gateways, but a silently remapped ID can route to a different model than you intended—with different latency and quality.
“Switching gateways means rewriting all model calls”
Not necessarily. If you abstract model creation behind a factory, you can swap baseURL and ID format in one place:
function getModel(id: string) {
return openai(id, { baseURL: env.GATEWAY_URL });
}
Call sites stay stable; only the ID convention changes when you move from native to gateway.
Migration and interoperability tips
- Centralize model IDs. Define a map from logical name (
smart,cheap) to gateway or native ID. - Validate against gateway catalog. At boot, fetch the gateway’s
/v1/modelsand warn if a referenced ID is missing. - Use the OpenAI-compatible adapter for multi-provider gateways. Since most gateways speak the OpenAI chat format, the
@ai-sdk/openaiadapter withbaseURLis the lowest-friction integration. - Preserve cache-control. If your gateway forwards
cache_controlhints (as Anthropic native does), ensure the SDK’s provider adapter emits them. The OpenAI adapter won’t send Anthropic-specific fields, so a gateway translating OpenAI→Anthropic must handle that mapping.
Reading the gateway’s model list
Most OpenAI-compatible gateways expose:
curl https://gateway.example/v1/models \
-H "Authorization: Bearer $KEY" | jq '.data[].id'
Output tells you exactly which strings are valid. If you see openai/gpt-4o in that list, the gateway uses namespaced IDs. If you see gpt-4o, native IDs work.
Summary of the contract
The Vercel AI SDK model ID naming gateway vs native boils down to a single question: what string does the receiving endpoint expect in the model field? The SDK is agnostic; it forwards your string. Your job is to match the gateway’s catalog and ensure the adapter’s request shape aligns with that gateway’s expectations. Get that right and the same application code can run against OpenAI, a single-provider gateway, or a 240-model routing layer without per-call changes.