AppAIGatewayDocs
Providers

Custom base URLs

Point a provider at an endpoint you control instead of the provider's own API.

A provider that authenticates with its own API key can carry an optional Base URL that replaces the provider type's own origin. Nothing else changes: the path after the slug, the query string, the credential header, the model rules and the pricing rule are exactly what they would have been.

The Base URL field

In the Add provider dialog, with Authentication set to API key, fill in Base URL (optional). Leave it empty to use the provider's own API. The field takes an absolute https:// URL, and the path you append after the slug is joined onto it:

Base URL:   https://my-vllm.example.com/v1/
Your app:   POST /v1/apps/my-app/proxy/vllm/chat/completions
Reaches:    https://my-vllm.example.com/v1/chat/completions

Click Test provider to run the provider type's test call at the new origin before saving. A custom endpoint that does not implement the provider's list-models call answers 404, which reports as unconfirmed rather than as a refusal.

The API equivalent:

POST /v1/admin/providers
{
  "type": "openai",
  "name": "Self-hosted Llama",
  "slug": "vllm",
  "secret": "...",
  "baseUrl": "https://my-vllm.example.com/v1/"
}

The field is not available with Use gateway. A gateway owns the upstream origin, and the API refuses baseUrl together with providerGatewayId on both create and update.

What it enables

Any server that speaks a supported provider's API unchanged becomes usable without a code change in your apps.

  • Self-hosted inference. vLLM, SGLang, Ollama behind TLS, llama.cpp's server. Pick openai as the type and point it at your /v1/ base.
  • A second region of a supported provider. BytePlus ModelArk's eu-west host, for instance, whose keys and catalogs are region-isolated. Pick bytedance as the type and enter that region's base URL.
  • A proxy of your own in front of a provider, as long as it speaks that provider's API unchanged.
  • Azure OpenAI, with the caveats below.

The console shows the origin under Auth in the Providers list, beside the key's last characters, so it is never a surprise which service a key is being sent to.

What the URL must look like

The URL is checked and rewritten into a canonical form before it is stored. Each rule refuses with a message naming what is wrong.

RuleRejected examples
https onlyhttp://..., ftp://...
No credentials in the URLhttps://user:pass@host/
No query string and no fragmenthttps://host/?api-version=..., https://host/#x
Default port only (443, explicit or implicit)https://host:8443/
A public DNS name, never an IP address in any formhttps://127.0.0.1/, https://0x7f000001/, https://[::1]/
At least two labels, valid DNS labels, no trailing dothttps://vllm/, https://host./, https://a..b.example.com/
No reserved local suffix.local, .localhost, .internal, .home.arpa, .lan, .corp, .test, .example
At most 200 characters

What is stored is the canonical form: lower-cased host (punycoded if you typed Unicode), no redundant :443, dot segments resolved, and exactly one trailing slash. https://My-VLLM.Example.com/v1 is stored as https://my-vllm.example.com/v1/.

Upstream redirects are never followed on any proxied request. A 3xx from your endpoint is passed back to the client as is, so a redirect cannot move the destination after the URL was checked.

Changing the origin

To move an existing provider to a different origin, open Update key on its row. The dialog has a Base URL field next to New API key, with the hint "Changing the origin needs the key above, because the stored key is never sent to a new origin. Leave empty to use the provider's own API."

That rule is the point. The stored key is write-only: it is never decrypted to be sent somewhere it has not been sent before, so pointing a provider at a new host cannot become a way to read its key back out. Paste the key again, set the new Base URL, and click Update key. Emptying the field returns the provider to the provider type's own API.

Through the API, a new baseUrl needs secret in the same request, and the update is refused with 400 invalid_request without it. Clearing needs nothing else:

PUT /v1/admin/providers/{id}
{ "secret": "sk-...", "baseUrl": "https://eu.example.com/v1/" }
PUT /v1/admin/providers/{id}
{ "baseUrl": null }

Send the same type, secret and baseUrl to POST /v1/admin/providers/test first to find out whether the key works at the new origin.

Security note

Pointing a provider at an origin hands that origin the key

The base URL is set only by you, through the console or a management key. No app and no end user can influence it; it is read from the stored provider, never from a request. Treat entering an origin as equivalent to giving that origin the provider's API key, because that is what every request does.

The checks above stop the direct expression of a mistake: a local address, a typo, a copied internal name. They cannot stop a public hostname from resolving to a private address, because the gateway does not resolve names itself and cannot see or pin the address a request connects to. The real control is that only you can write this field.

Custom endpoints still need prices

A model served from your own endpoint is almost certainly not in the shipped catalog, so it is refused with 400 pricing_not_configured until you enter a price for it under the provider's Pricing action. Entering the price is what allows the model. There is no "unmetered because it is mine" path.

For a model you host yourself and pay no per-token price for, $0 is enterable. Enter it deliberately, because it also removes that traffic from every spending limit. See Model pricing.

Azure OpenAI

Use provider type openai with the resource's v1 base URL:

https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/

Azure's v1 API accepts the resource key as Authorization: Bearer, which is exactly what the gateway sends for the openai type. It is the same thing Microsoft's own documentation does when it runs the stock OpenAI SDK against that base URL. Two things to know:

  • The older, dated Azure surface is not supported. It authenticates with an api-key header and needs an ?api-version= query on the base, neither of which the gateway adds. The URL check refuses a base URL carrying a query string for that reason. Use the v1 base URL above.
  • Microsoft Entra ID tokens are not supported. They are short-lived and need refreshing, and a provider stores one static secret. Use a resource key.

The model field in your requests is your deployment name, not the upstream model name, and deployment names are not in the shipped catalog. Price them on that provider as described above.

On this page