Vercel AI Gateway
The Vercel AI Gateway speaks the OpenAI and Anthropic wire protocols, so you reach it with an ordinary provider client pointed at a different base URL. How you capture it depends on which language you are in, and the two answers are genuinely different.
| Language | How to capture gateway traffic |
|---|---|
| Python | Wrap an OpenAI or Anthropic client whose base URL is the gateway |
| TypeScript | Use the AI SDK middleware on a gateway() model |
Python
Section titled “Python”Point the official client at the gateway and wrap it. Metergraph recognizes the public gateway host automatically.
import osimport metergraphfrom openai import OpenAI
gateway = metergraph.wrap(OpenAI( api_key=os.getenv("AI_GATEWAY_API_KEY") or os.getenv("VERCEL_OIDC_TOKEN"), base_url="https://ai-gateway.vercel.sh/v1",))
gateway.chat.completions.create( model="anthropic/claude-sonnet-4.6", messages=[{"role": "user", "content": "Hello"}],)An Anthropic client pointed at the same host works the same way.
Detection is an exact hostname match on a parsed URL, never a substring. The
host must be ai-gateway.vercel.sh. A path such as /v1 makes no difference,
and a lookalike host such as ai-gateway.vercel.sh.example.com is not
detected.
Custom gateway URLs
Section titled “Custom gateway URLs”If your gateway sits behind your own domain, the host will not match. Declare it:
gateway = metergraph.wrap(client, provider="vercel")"gateway" and "vercel-ai-gateway" are accepted as the same thing.
What the row looks like
Section titled “What the row looks like”On the gateway path the request model is a creator-qualified identifier such as
anthropic/claude-sonnet-4.6. Metergraph takes the provider from the part
before the slash, and keeps the full identifier as the model. So a call to
anthropic/claude-sonnet-4.6 is recorded with provider anthropic, and sits
alongside your direct Anthropic calls in the dashboard rather than in a
category of its own. A model with no slash is recorded with the provider
vercel-ai-gateway.
Pricing is resolved on the server from the effective-dated catalog, at read
time. A model the catalog does not know stays visible and lands in the
unpriced bucket instead of being dropped. See
Model catalog and pricing.
Streaming behaves exactly as it does for a direct OpenAI chat completion,
including the stream_options handling described under
OpenAI.
The batch-result readers are not attached on the gateway path. Only the inference seams are patched.
TypeScript
Section titled “TypeScript”The Node wrap() does not detect the gateway host. Capture gateway traffic
through the AI SDK middleware instead, which canonicalizes the provider from
the same creator/model prefix:
import * as mg from "metergraph";import { gateway, generateText, wrapLanguageModel } from "ai";
const model = wrapLanguageModel({ model: gateway("anthropic/claude-sonnet-4.5"), middleware: mg.vercelAISDKMiddleware(),});
await mg.trace("support-answer", () => generateText({ model, prompt: "Help this customer" }));The middleware recognizes gateway, vercel and vercel-ai-gateway as
gateway provider names and resolves the real provider from the model
identifier’s creator prefix, so anthropic/claude-sonnet-4.5 is recorded as
anthropic here too.
Full setup, including the AI SDK version options, is on Vercel AI SDK.
- Vercel AI SDK for the middleware in full
- OpenRouter for the other supported gateway
- Model catalog and pricing for how a
creator/modelidentifier is priced