Skip to main content
A gateway sits between Oxygen and a model provider — for cost control, key custody, failover, regional routing, or access to many models through one endpoint. Most expose an OpenAI-shaped API, so Oxygen talks to them through the openai_compat vendor.

The one thing that trips everyone up

vendor: openai and vendor: openai_compat speak different protocols: Nearly every gateway implements Chat Completions only. Pointing vendor: openai at one returns a 404 that reads like an outage or an auth problem but is neither — the path simply isn’t there. If you see this, change the vendor, not the key:

Quick start

config.yml
Store the value under Settings → Secrets with the name matching key_var exactly. On Oxygen Cloud the workspace secret store is the only source — a .env file is read in local mode only. api_url must be the root of the OpenAI-shaped API; Oxygen appends /chat/completions. It is required for openai_compat — there is no sensible default host for a gateway, and defaulting would silently send your traffic to OpenAI. Then point an agent at it:
agents/analytics.agentic.yml

Recipes

Attribution headers (HTTP-Referer, X-Title) are optional — add them via a headers: block if you want them.
All follow the same shape — only api_url and model_ref change:
Azure has its own deployment-scoped URL shape, so it stays on vendor: openai with two extra fields:
Oxygen builds the full /openai/deployments/{id}/chat/completions?api-version=… URL for you.

Using a gateway without editing config.yml

If a model is already defined as vendor: openai, an agentic agent can inherit its key and api_url while overriding only the protocol:
analytics.agentic.yml
An explicitly-written llm.vendor always wins over the vendor implied by ref.
This route inherits the referenced model’s api_url including its default. A vendor: openai model that omits api_url falls back to https://api.openai.com/v1, so the override would send traffic to OpenAI over Chat Completions. If you are using a gateway for data-residency reasons, make sure the referenced model pins api_url — or define a proper openai_compat model, which requires it.

Gateways that need a custom header

Some gateways authenticate or route on their own header rather than the bearer token. Add a headers: block — values can be inline or pulled from a secret:
config.yml
The same shape covers Helicone (Helicone-Auth), an authenticated Cloudflare AI Gateway (cf-aig-authorization), and OpenRouter’s optional HTTP-Referer / X-Title attribution headers. Custom headers are sent in addition to the standard content-type and Authorization — they are not a way to replace them. A header whose secret can’t be resolved is skipped with a warning rather than failing the run, so the gateway’s own error surfaces instead of a config-load failure.

Anthropic-shaped gateways

vendor: anthropic honours api_url, so an Anthropic-compatible proxy works directly:
api_url is the root, consistent with the OpenAI vendors — Oxygen appends /messages, just as it appends /responses and /chat/completions. The default is https://api.anthropic.com/v1.

Not supported

Gateways that don’t expose an OpenAI-shaped API — AWS Bedrock (SigV4 request signing) and Vertex AI’s native API — need a dedicated vendor. Vertex’s OpenAI-compatible endpoint can work via openai_compat, but its access tokens are short-lived, so you’d have to refresh the secret.

Troubleshooting

Testing a gateway setup

scripts/fake-llm-gateway/ in the Oxygen repo runs a local stand-in that 404s /responses, serves /chat/completions, and logs whether your key reached the Authorization header — useful for confirming a config before pointing it at a paid provider.