AppAIGatewayDocs
Providers

Supported providers

The sixteen provider types, the native path each one expects, and which gateways can carry them.

Every provider you add has a type. The type fixes the upstream API, the authentication header the gateway sends, and the price catalog the model is looked up in. The path after the slug is always the provider's own, verbatim, without a leading slash:

/v1/apps/{app}/proxy/{slug}/{provider-path}

The OpenAI-compatible providers disagree about their prefix more than about anything else, so the exact chat-completions path is listed for each.

All provider types

TypeServiceChat completions pathThrough a gatewayNotes
openaiOpenAIv1/chat/completionsCloudflare, VercelAlso v1/responses, v1/audio/transcriptions.
anthropicAnthropicv1/messagesCloudflare, VercelAnthropic Messages, not chat completions.
xaixAI (Grok)v1/chat/completionsCloudflare, VercelAlso v1/responses, v1/stt.
geminiGoogle AI Studiov1beta/openai/chat/completionsCloudflare, VercelNative API at v1beta/models/{model}:generateContent.
perplexityPerplexitychat/completionsCloudflare, VercelSonar models. No test call.
deepseekDeepSeekchat/completionsVercelNo v1/ in the base URL.
moonshotMoonshot AI (Kimi)v1/chat/completionsVercelInternational api.moonshot.ai host.
groqGroqopenai/v1/chat/completionsDirect onlyOpenAI API namespaced under openai/.
mistralMistralv1/chat/completionsDirect only
togetherTogether AIv1/chat/completionsDirect onlyModels are namespaced, for example openai/gpt-oss-120b.
fireworksFireworks AIinference/v1/chat/completionsDirect onlyNo catalog; price your models. No test call.
cerebrasCerebrasv1/chat/completionsDirect only
huggingfaceHugging Face Inference Providersv1/chat/completionsDirect onlyNo catalog; pin the upstream in the model ID. No test call.
basetenBaseten Model APIsv1/chat/completionsDirect only
bytedanceBytePlus ModelArkchat/completionsDirect onlyVersion segment is already in the base URL. No test call.
openrouterOpenRouterv1/chat/completionsDirect onlyThe only path it accepts. Reports its own cost.

The console shows these labels in the Provider picker: OpenAI, Anthropic, xAI, Gemini, Perplexity, DeepSeek, Groq, Mistral, Together AI, Fireworks AI, Cerebras, Moonshot AI, Hugging Face, Baseten, ByteDance Ark, OpenRouter.

"Direct only" is the default, not a limitation of the type. A provider type is offered on a gateway once that pairing has been verified against the gateway's live catalog, because a provider slug or model namespace guessed from documentation is a guess about a URL and about which keys the gateway holds. Connect these types with their own API key.

The paths in the table are for providers that call the provider's own API. A provider routed through a gateway uses the gateway's paths instead. See Gateways.

Using an SDK

For the OpenAI SDK, set the base URL to https://api.appaigateway.com/v1/apps/YOUR-APP/proxy/openai/v1. The SDK then appends standard paths such as responses or chat/completions. The same works for any OpenAI-compatible provider: point the base URL at that provider's slug and its prefix, for example /proxy/groq/openai/v1. Request bodies and responses keep the provider's native format. See Calling the proxy.

Caveats by provider

A few types carry caveats worth knowing before you add a key.

ByteDance is the international BytePlus ModelArk endpoint in ap-southeast-1, and /api/v3 is already part of the base URL, so the path is chat/completions with no version segment of your own. Keys and model catalogs are region-isolated, and models must be activated in your ModelArk console before they answer. The China Volcengine edition is a separate service and is not reachable here. For another region, set a custom base URL.

Moonshot is the international api.moonshot.ai host. A key issued on the China platform will not work.

Fireworks names models per account (accounts/{account}/models/{id}), so no shipped catalog could be right for your account. Price the models you use under the provider's Pricing action. See Model pricing.

Hugging Face routes each request to whichever upstream it picks, and the same model costs up to ten times more on one upstream than another. Pin the upstream in the model ID (author/model:provider) and price that ID, or the recorded cost is a guess.

Gemini has two APIs. The OpenAI-compatible one lives at v1beta/openai/chat/completions; the native one at v1beta/models/{model}:generateContent. Both work on a direct or Cloudflare-routed Gemini provider. Only the OpenAI-compatible one works through Vercel.

Groq namespaces its OpenAI API under openai/, DeepSeek and ByteDance have no prefix at all, and Fireworks separates its inference plane from its control plane. Copy the path from the table rather than assuming v1/.

OpenRouter is an aggregator, and the only type that records the cost the upstream reports rather than a locally computed one. It has a section of its own below.

What Test provider calls

Test provider in the Add provider dialog, and POST /v1/admin/providers/test behind it, run the cheapest authenticated call the provider offers. A provider is missing from this table only when it has no call that can prove a key. That is deliberate: a test against a URL that answers 200 regardless of the credential would report every key as good.

ProviderTest call
OpenAIGET v1/models
xAIGET v1/models
AnthropicGET v1/models
GeminiGET v1beta/models
DeepSeekGET models
GroqGET openai/v1/models
MistralGET v1/models
Together AIGET v1/models
CerebrasGET v1/models
Moonshot AIGET v1/models
BasetenGET v1/models
OpenRouterGET v1/key, its key-status call. Its model list is public and would pass any key.
PerplexityNone. Accepted unchecked.
Fireworks AINone. Its model list needs an account ID the key does not carry.
Hugging FaceNone. Its model list answers 200 to any token.
ByteDanceNone. ModelArk publishes no list-models call.

The verdicts are explained in Add a provider key.

OpenRouter

OpenRouter is treated as a provider type, not as a gateway. It is the counterparty that charges you, and its catalog includes models with no direct provider at all. Two things follow.

Its slugs are the model IDs. google/gemini-3.6-flash and meta-llama/llama-4-maverick are the model IDs here. They are what you send, what an app's allowed models and fixed models match, and what a usage event records. They are not translated: an OpenRouter provider and a direct Gemini provider name the same model differently, so moving an app between them means renaming the model. The leading namespace is also where the model's author comes from, so usage groups by Google or Meta the same way it does on a direct route.

Cost is reported, not computed. Every OpenRouter chat-completions response carries usage.cost, what OpenRouter actually charged for that request. The gateway records it as the event's cost with cost_source: "reported". So OpenRouter models proxy with no local price: the pricing rule is satisfied by the route reporting its own cost, which is why no OpenRouter section ships in the catalog. Streaming works the same way; the figure arrives in the final chunk.

If a response ever comes back without a cost, the event is not recorded at zero. A custom price for that model is used if you have entered one (computed), and otherwise the event is marked unresolved.

Bring your own key: two figures, both yours. When a request runs on your own upstream provider key, OpenRouter's usage.cost is only its own fee (5% of what the request would have cost on OpenRouter), while the provider charges your key directly for the inference and OpenRouter reports that separately as usage.cost_details.upstream_inference_cost. The two are disjoint, so the gateway records their sum: both numbers left your accounts.

Aborted streams are not reconciled

The cost arrives in the final chunk of a stream, so a client that disconnects before it leaves the request unresolved at $0 in your usage, even though OpenRouter charged for the tokens generated up to the disconnect. Watch the unresolved count on OpenRouter providers, and set per-user limits on the apps that route through them. Those bound how much can go unmeasured before you notice.

OpenRouter providers accept chat completions only, at v1/chat/completions. OpenRouter does serve other APIs, but only its chat-completions response reports a cost, and a request the gateway could not account for is refused with 403 api_style_not_supported rather than served for free.

One request-shaping detail, invisible to your client's SDK: the gateway asks OpenRouter, with a header, to name the endpoint it routed to. Your request body is forwarded byte for byte. That answer is stored as served_provider (shown as Served by in the app's usage view), along with served_model, and credential_source: "byok" when the response says the inference was paid for with your own upstream key. All three are absent when OpenRouter does not say. See Usage.

On this page