Skip to main content
This guide is for admins. The gateway has to be configured — credentials, providers, models, and routes — before anyone can call it. For an overview and architecture first, see Using the LLM Gateway. If your admin has already set this up and you just want to point a tool at it, go to Connecting Your Tools to the LLM Gateway.

Admin: Configure the Gateway

All admin configuration happens in LLM Management in the Barndoor portal — a single hub whose left-hand nav groups every piece of the gateway. Work top to bottom: connect a provider, enable models, give them route names, mint a key, send a test request, then layer on governance.
Launch Profiles, Routing Policies, and Routing Rules appear only when those features are enabled for your organization — contact Barndoor if you need them. In some organizations the Models section is replaced by a Models panel on each provider’s detail page; see Step 3.
Per-request usage and cost reporting lives separately, under Reporting → LLM Usage Dashboard — see Reading the LLM Usage Dashboard.
LLM Management hub showing the Connections, Models, Keys, and Controls section groups in the left navigation

Step 1: Add Provider Credentials

Credentials are what authorize Barndoor against your upstream account. Save them once in LLM Management → Credentials and any number of providers can use them. You can also skip this step and create credentials inline while creating the provider in Step 2 — they’re saved to the Credentials section either way. The two OAuth passthrough providers store no credentials at all and are set up entirely on the Providers section:
Add Credentials dialog with the Model Provider picker, name, base URL, API key, and reason fields
The simplest case — pick the provider and paste a key.
  1. Click Add Credentials. The dialog opens with a Model Provider picker at the top; the rest of the form is disabled until you pick one.
  2. Pick the provider. The Base URL fills in with the catalog default, and any provider-specific fields appear.
  3. Give the credentials a Name (for example Production Anthropic Key) — this is how you’ll find them when creating a provider.
  4. Paste the API key.
  5. Click Create. The key is stored in Barndoor’s encrypted secret store and is never returned to the browser.
To connect an OpenAI-compatible service that isn’t in the catalog, pick the custom option in Model Provider and enter its base URL and key yourself.
Bedrock supports three authentication methods, chosen in Bedrock Auth Method. AWS IAM Role is the recommended production setup; the others are useful for pilots or environments that can’t grant cross-account roles.Every method needs an AWS Region — where Barndoor sends Bedrock Runtime requests (for example us-east-1). Make sure the models you want are enabled in that region in AWS.
Which Bedrock API the gateway calls — Claude / Anthropic Messages or Bedrock Converse — is chosen per provider (Bedrock API Family, in Step 2), not on the credentials. One IAM role can back a provider for each family.

Setting up an AWS IAM Role

The dialog walks you through this with a Bedrock setup checklist.
  1. Pick AWS IAM Role as the Bedrock Auth Method.
  2. Fill in AWS Region and your Customer IAM Role ARN. Barndoor generates an External ID and shows its own Barndoor Principal ARN for this environment in the same dialog.
  3. Click Copy trust policy — Barndoor builds the JSON for you, pre-filled with its principal ARN and your external ID.
  4. In AWS IAM, create (or update) the role you named in step 2 and paste the copied trust policy into its trust relationship.
  5. Grant the role permission to invoke Bedrock — at minimum bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream. (The AWS-managed read-only Bedrock policies do not include these actions.) For a proof of concept, Resource: "*" is fine; for production, narrow Resource to the specific Bedrock model ARNs / inference profiles and regions you route to.
  6. Back in Barndoor, click Validate role access. The portal attempts the same assume-role chain it uses at runtime and shows the AWS error verbatim if something’s off — adjust the trust policy or role permissions until it validates.
  7. Click Create. The AWS Trust Info dialog opens; you can reopen it any time from the credentials’ row menu (AWS trust info) to recheck the principal or external ID.

Setting up Static AWS Keys

Paste the AWS Access Key ID, AWS Secret Access Key, and an optional AWS Session Token (if you’re using temporary credentials). There’s no validate button for this mode — failures show up on the first real request.

Setting up a Bedrock API Key

Paste the Bedrock API Key issued by the AWS Bedrock console.
Vertex supports three authentication methods, chosen in Google Auth Method:Every method needs:
  • GCP Project ID — your project.
  • Vertex AI Location — the region (default us-central1).

Setup steps

  1. Pick the auth method and fill in the fields.
  2. In your GCP project, enable the Vertex AI API and any partner-model access (for example, Claude on Vertex requires explicit model enablement).
  3. Grant roles/aiplatform.user (or a narrower Vertex role) on the project to whichever principal actually calls Vertex — Barndoor’s runtime identity (Workload Identity / ADC), your target service account (impersonation), or the key’s service account.
  4. For Service Account Impersonation only: grant roles/iam.serviceAccountTokenCreator on your target service account to Barndoor’s runtime principal.
  5. Click Validate Vertex Access. Barndoor fetches a token with your chosen method and asks Vertex about a model, confirming that both auth and model access work.
The Service Account Key method asks for the email and private key as separate fields, plus an optional Token URI. Paste the values into the form — uploading the raw JSON file is not supported.
Which Vertex API the gateway calls is chosen per provider (Vertex API Family, in Step 2): Gemini Generate Content, Claude / Anthropic Messages, or OpenAI-compatible (Model Garden MaaS, e.g. GLM).
Gemini on Vertex doesn’t support streaming, tool calls, or structured response_format through the gateway yet. Streaming requests to a Gemini Generate Content provider are rejected with a 400. Claude on Vertex and the OpenAI-compatible family stream normally. For Gemini with streaming, use a Google AI (Gemini) provider instead.
Microsoft Foundry (formerly Azure AI Foundry) serves Claude and OpenAI GPT / o-series models from one Foundry resource. Pick the method in Azure Auth Method:Some Foundry Claude models are only reachable with Entra ID.Which of the resource’s model APIs a provider targets — Claude (Anthropic Messages) or GPT / o-series (Azure OpenAI) — is chosen per provider (Model API Family, in Step 2), so one set of credentials covers both.
Use this when your developers use Claude Code with their own Claude subscriptions and you want each request billed against that developer’s subscription rather than a shared API key.Instead of storing a Claude API key, Barndoor authenticates the caller with their bd-… gateway API key and forwards the caller’s own Claude OAuth token (sk-ant-oat…) to Anthropic on the upstream request.
Anthropic OAuth passthrough is configured on the Providers section — there’s nothing to save in Credentials.

Setup

  1. Go to Providers → Add Provider and pick the Anthropic OAuth card (one of the two Anthropic cards).
  2. Name the provider (for example Anthropic via Claude OAuth). Credentials shows Claude OAuth passthrough — no stored credential, and no API key field appears.
  3. Click Create, and enable the Claude models you want to expose.
  4. Add those models to a Model Route.
You can also switch an existing Anthropic provider to passthrough by setting its Authentication to Claude OAuth passthrough.

What callers send

Every request carries two headers:Claude Code sends both automatically — see the Claude Code section of Connecting Your Tools to the LLM Gateway for the setup.

Smoke-test with curl

To verify the two-header path without Claude Code:
A 200 with a normal Anthropic response body confirms both headers flowed correctly. A 401 means one of the two headers is missing or malformed.

Limitations to know about

  • Endpoint scope: the Claude OAuth token is forwarded only on POST /v1/messages. A request that reaches an Anthropic OAuth provider through any other endpoint — for example /v1/chat/completions — fails with 401 and the message Anthropic provider requires an incoming Claude OAuth bearer token. (/v1/messages/count_tokens is answered by the gateway itself and never reaches Anthropic.)
  • Token management: Barndoor never stores or refreshes Claude OAuth tokens. Expiry and refresh are handled by Claude Code on the developer’s machine.
  • A missing token doesn’t fail over. It’s treated as a caller error (401), not an upstream failure, so the gateway doesn’t move on to the route’s other targets.

Pairing OAuth with a fallback

A common production setup puts the OAuth provider first and a cheaper or shared provider second on the same route, so each developer’s subscription absorbs everyday traffic and the fallback takes over when the subscription hits its limit or Anthropic is degraded. Get the most out of your Claude subscription walks through that setup end to end.
Credentials are encrypted at rest and never leave Barndoor in the clear once saved. When you rotate an upstream key, update it on the credentials in Barndoor; every provider that uses them picks up the new value.

Step 2: Create a Provider

A Provider is a named upstream connection that uses one set of credentials. Open Providers and click Add Provider to open the Add a Provider card grid:
  1. Search, or filter the catalog with All / Official / Custom. Official cards come from Barndoor’s provider catalog (see Supported Providers). The Custom Provider card connects any OpenAI-compatible endpoint you configure yourself.
  2. Click the card for the upstream you want. Anthropic shows two cards — the standard API-key card and Anthropic OAuth. A dialog opens with the catalog defaults filled in.
  3. Give the provider a Name. Pick it with care: it appears in the providers list, in usage reports, and in the provider-prefixed model names callers can use (for example OpenAI Prod/gpt-5.4-mini).
  4. For AWS Bedrock, Google Vertex AI, and Microsoft Foundry, pick the provider’s API family — Bedrock API Family, Vertex API Family, or Model API Family. It decides which models this provider can serve. To use more than one family from the same account, create one provider per family, all using the same credentials.
  5. Pick the Credentials — a saved set from Step 1, or + Create new credentials to enter them here. New credentials are given a Credential name and saved to the Credentials section, where other providers can reuse them.
  6. Review the provider settings:
  7. Click Create (Create and add route for AWS Bedrock). If Auto-Sync is Off, an Enable Models dialog opens next — continue with Step 3 there, or click Skip.
You can create several providers from the same vendor or even the same credentials — for example one for production OpenAI and one for an Azure OpenAI deployment in another region. The providers list shows each provider’s credentials, a Source column (Official or Custom) you can filter on, and a status pill.
For Azure OpenAI (and Foundry GPT providers), Azure API Mode chooses between OpenAI v1 paths (default) and Deployment paths (dated api-version). Deployment paths don’t serve the Responses API, so Codex and other Responses clients need the v1 mode.

Provider health

Barndoor tracks whether each provider is reachable and serving, and shows it as a status pill on the provider’s row: When a provider is failing, hover the pill to see the underlying error, and use Re-check health from the row’s menu to re-run the check straight away (useful right after you fix a credential or trust policy). Unhealthy targets are skipped during failover, so one degraded provider doesn’t take down a route that has healthy fallbacks.
Add OpenAI provider dialog with the health-check, Auto-Sync, Calculate token cost, and Credentials settings

Step 3: Enable Models

A provider serves only the models enabled on it. If you skipped the Enable Models dialog, or want to change what’s enabled later, open the Models section: each provider is listed with its models, and you toggle on every upstream model your organization should be able to call (for example gpt-5.4-mini, claude-sonnet-5, text-embedding-3-large). To add a model that isn’t in Barndoor’s catalog, type its exact upstream name as a custom model. These are the upstream model identifiers — the names sent to the provider. An enabled model is immediately callable by its provider-prefixed name, <provider name>/<model> (for example OpenAI Prod/gpt-5.4-mini). To give it a plain name, add it to a route in Step 5.
In some organizations the Models section is replaced by a Models panel on each provider’s own page: click the provider’s name on Providers, then enable models there. The panel also has Sync now for providers with Auto-Sync on.
If Require pricing for Model Routes is on, a model can’t be enabled until it has a price — a model without one shows an Add pricing shortcut that takes you to Model Pricing.
Models panel on a provider's page, listing enabled upstream models with their prices

Step 4: Configure Model Pricing (optional)

Barndoor already prices every request against its managed default catalog of market-rate prices, so the cost-aware features work without any setup:
  • Spending budgets in LLM Controls
  • The estimated cost recorded for every request
  • Per-team, per-user, and per-model cost on the Reporting → LLM Usage Dashboard
Use Model Pricing only when you want to override those defaults — negotiated rates, custom models, or prices you’d rather manage yourself. See Managing Model Pricing for the full guide, including the Require pricing for Model Routes safety setting.

Step 5: Define Model Routes

This is the step that gives callers a stable model name. A Model Route maps a client-facing model name to one or more enabled provider models, tried in priority order.
  1. Open Model Routes and click Create Route.
  2. Enter the Route Name callers will use, for example gpt-5.4-mini or team-coding-model. This is the value callers put in the model field.
  3. Pick a provider in Browse provider and check one or more of its Provider Models. Switch Browse provider to add targets from other providers to the same route.
  4. Optionally open Advanced settings to set per-target Rate limit retries and Timeouts.
  5. Click Create Route.
The first target is the primary. If it fails with a failover-eligible error — a 5xx, a network error, a timeout, or a 429 that outlasts its retries — the gateway tries the next target. You can reorder targets after the route is created. See Failover, Cooldowns, and Route Health for exactly which errors fail over.
Create Model Route dialog with the route name eng-claude-opus-5-5 and claude-opus-5-5 selected on two providers, Anthropic OAuth and Anthropic API
Backing one route with more than one provider. A gpt-5.4-mini route can have one target on an OpenAI provider and a second on an Azure OpenAI provider. Callers send gpt-5.4-mini and the gateway tries the targets in order, failing over if one errors. To reach one specific provider with no failover, callers use that provider’s own model name instead — OpenAI Prod/gpt-5.4-mini — as described in Model Naming.
Route Groups (next to Create Route) bundle routes so a single model access policy can cover the whole group instead of listing every route.

Step 6: Create an API Key

To send a test request you need a bd-… key. Either:
  • Create your own under Settings → My Models → API Keys → Create Key, or
  • Create one in LLM Management → API Keys → Create Key. Give it a Name, then optionally Assign to User or Assign to Group. Leave both unset for an organization-wide key — the usual choice for services and CI. Group members share group-scoped budgets, rate limits, and model access.
The key is shown once, in the API Key Created dialog. Copy it before closing — Barndoor keeps only a hash.
Where agents are connected to the LLM Gateway, Create API Key also offers Assign to Agent, so the key’s usage is attributed to that agent. A key belongs to at most one of a user, a group, or an agent. This option may not be enabled for your organization yet — contact Barndoor if you need it.

Step 7: Send a Test Request

List the models your key can call, then send a request to one of them:
Replace gpt-5.4-mini with a route name from Step 5 (or a provider/model name from Step 3). A 200 with a normal chat completion means the gateway is working end to end. The request shows up on Reporting → LLM Usage Dashboard. If it fails, see Troubleshooting.

Step 8: Add Governance (optional)

Once routes are live, layer on usage policies. They live under the Controls group of LLM Management and are enforced inside the gateway on every request, so they apply to every client and SDK alike.
  • Budgets — token and spending caps per period, with alert thresholds.
  • Rate Limits — request and token throughput caps.
  • Model Access — allow or deny specific models and routes for the organization, a group, a role, a user, or an API key.
See Configuring LLM Controls for scopes, the order Barndoor evaluates policies in, and what callers see when a request is denied.

Sending Requests

The gateway speaks two API dialects on the same base URL, https://app.barndoor.ai/api/llm-gateway/v1: Send your key as Authorization: Bearer bd-… or x-api-key: bd-…. When both headers are present the gateway reads the key from x-api-key, so Anthropic-compatible clients can pass a provider-side OAuth token in Authorization. Request bodies can be up to 32 MB by default, enough for a full-context Claude Code conversation.

List Available Models

Enumerate what a key can call instead of hardcoding model names — the set changes as admins add providers, enable models, or adjust access policies.
Note the two base URLs differ: the OpenAI client takes the /v1 form, the Anthropic client the bare one — it appends /v1 itself. Both are shown on the LLM Gateway Endpoint card under Settings → My Models → Gateway Endpoint for your own tenant. The listing is filtered by the policies that apply to your key, so it reflects what that key can actually invoke rather than the organization’s full inventory. The response shape follows the client. The request above returns the OpenAI envelope ({"object": "list", "data": [...]}), which is the default. Send an anthropic-version header — as the Anthropic SDKs and Claude Code do — or authenticate with x-api-key and no Authorization: Bearer header, and you get Anthropic’s envelope instead ({"data": [{"type": "model", "id": …, "display_name": …}], "has_more": false}), so client.models.list() parses against either SDK:
Each entry also carries an additive barndoor object — the serving provider and upstream model (when every target agrees on them), whether the name is a multi-target fallback group, and how many targets it has. It is extra metadata on top of the standard fields, so strict OpenAI and Anthropic clients ignore it safely.

Non-Streaming Chat Completion

Streaming Chat Completion

Set "stream": true and the gateway streams the response back as server-sent events in the format of the endpoint you called, whichever provider serves it.

Embeddings

Anthropic Messages (Claude Code)

The gateway also accepts native Anthropic-style requests:

Connect Your Tools

Cursor, Claude Code, Codex, LangChain, the OpenAI and Anthropic SDKs, and plain curl each need your API key, a model route name, and the gateway endpoint. Step-by-step configuration for each lives on its own page:

Connecting Your Tools to the LLM Gateway

Create a key, copy your model route and endpoint, and wire up your editor, agent, or SDK.

Model Naming

The string in the model field decides how the gateway routes the request. There are three forms: The prefix is the provider’s Name as configured in Providers, matched case-insensitively — not a fixed vendor slug. So openai/gpt-5.4-mini works only if a provider is named openai; a provider named Azure OpenAI Prod is addressed as Azure OpenAI Prod/gpt-5.4-mini. The part after the prefix is always an upstream model name, never a route name. To pin one target of a route, address that target’s upstream model directly on its provider; <provider>/<route name> returns 404.
If your organization requires routing policies, only routing policy names are callable — route names and provider-prefixed models are refused, and GET /v1/models lists only routing policies. See Require requests to use a routing policy.
Don’t guess names: GET /v1/models returns every identifier the calling key can use, already filtered by your model access policies. Call it once on startup rather than on every request.

Observability Headers

Successful responses on POST /v1/chat/completions and POST /v1/messages include headers you can log to understand routing — useful for client-side monitoring, comparing providers, and post-incident analysis. These are emitted on successful responses only — not on errors, and not on /v1/completions, /v1/embeddings, or /v1/responses. Every response, including errors, also carries x-bd-request-id. Send your own x-bd-request-id (or x-request-id) on the request and the gateway echoes it back; otherwise it generates one. Include it when you contact support. For per-request usage and cost, use Reporting → LLM Usage Dashboard in the Barndoor portal (guide), where you can break traffic down by model, provider, user, group, API key, status code, and more.

Failover, Retries, and Streaming

  • If a target returns a 5xx, a network error, a timeout, or a 429 that outlasts its retry budget, the gateway tries the next target in the route’s priority order. The response headers above show which target served the request.
  • Same-target 429 retries are configured per target (Rate limit retries in the route’s advanced settings). The gateway retries with backoff, then either succeeds or fails over.
  • Targets that keep failing are put in a short cooldown and skipped until they recover, and providers failing their health check are skipped too (see Provider health) — so failover prefers targets that are actually up. A provider with Block traffic on failed health check turned off stays in the rotation regardless.
  • A streaming request fails over if the upstream sends no response within 60 seconds.
  • Streaming responses (stream: true) preserve the provider’s SSE framing and pass through token usage where the provider reports it.
For the full rules, see Failover, Cooldowns, and Route Health.

Troubleshooting

Gateway errors use the error shape of the endpoint you called: {"error": {"message", "type", "code"}} on OpenAI endpoints, and {"type": "error", "error": {"type", "message"}} on /v1/messages. The message says what went wrong; the type is the stable value to branch on.
  • Confirm the header is Authorization: Bearer bd-… (with a space after Bearer) or x-api-key: bd-….
  • Make sure the key hasn’t been revoked or disabled (check Settings → My Models → API Keys or LLM Management → API Keys).
  • Keys only work in the organization and environment they were created in. A key from a trial environment won’t work against production, and vice versa.
  • A 401 that names a provider (for example Anthropic provider requires an incoming Claude OAuth bearer token) is about the upstream side — see the OAuth passthrough limitations in Step 1.
  • Call GET /v1/models to see exactly which names your key can use.
  • If you expected a name to be there, check with an admin that the route exists in Model Routes with at least one enabled target, and that the model is enabled on its provider.
  • model '…' not found for provider '…' means a provider-prefixed name didn’t match. The part after / must be an upstream model enabled on that provider — not a route name. Call a route by its plain name.
  • Model access denials read Model '…' is not allowed by access policy. Check LLM Management → Model Access for the policy that applies to the key’s user, group, or role. See Configuring LLM Controls.
  • Barndoor’s rate limits (type: rate_limit_error, with a Retry-After header) and budgets (type: budget_exhausted) can return 429 before the request reaches any provider. The message says which limit fired.
  • Upstream 429s are retried per the route’s retry settings and may then fail over. Check the x-bd-provider-retry-count and x-bd-provider-failover-count headers to see what happened.
  • When every target on a route fails, the message lists the providers tried and the last failure, and error.metadata.attempts has the detail for each attempt. The status matches the upstream failure where they all agree (for example 401 if every provider rejected its credentials), 429 if every attempt was rate limited, and 502 otherwise.
  • An attempt that timed out has a code starting with upstream_timeout_ (for example upstream_timeout_first_byte when a streaming request got no response within 60 seconds).
  • Check the providers’ status pills in Providers — see Provider health.
  • Gemini on Google Vertex AI doesn’t support streaming, tool calls, or structured response_format through the gateway yet. Send a non-streaming request, or route to a Google AI (Gemini) provider or a Claude model instead.
  • Make sure your HTTP client supports SSE and doesn’t buffer (curl -N, requests.post(..., stream=True), fetch with a manual reader, and so on).
  • A premature close usually means the upstream provider closed first. Check the failover headers and the LLM Usage Dashboard for that request.
  • The Anthropic SDK appends /v1/messages itself: set its base URL to https://app.barndoor.ai/api/llm-gateway (without /v1). Both forms are on the Gateway Endpoint card.
  • Send the Barndoor key in x-api-key. If your client only knows ANTHROPIC_API_KEY, set that to your bd-… key — it’s sent in the same header.

Frequently Asked Questions

No. Any HTTP client that can speak OpenAI’s request/response shape — or Anthropic’s Messages shape on /v1/messages — works. SDKs are a convenience, not a requirement.
In Barndoor’s encrypted secret store, attached to Credentials. The gateway loads them at request time; they’re never shown in the browser or returned by any API.
Yes. Reporting → LLM Usage Dashboard shows usage and cost by user, group, model, provider, and API key. Costs come from Barndoor’s default prices unless you override them in Model Pricing.
  • User keys (Settings → My Models → API Keys, or an admin key assigned to a user) are tied to one user. Usage and policies attribute to that user.
  • Group keys (assigned to a group in LLM Management → API Keys) share that group’s budgets, rate limits, and model access.
  • Org keys (no user or group) are typically used for services and CI. They have an organization scope but no individual user.
If the route has more than one target, the gateway fails over automatically and the response headers show which target succeeded. If every target fails, the caller gets an error listing each attempt — see the 502 entry in Troubleshooting.

Need Help?

Reach out to [email protected] with:
  • The endpoint you called, the HTTP status code, and the error.message.
  • The x-bd-request-id response header, or the approximate time of the request and the value you sent in the model field.
  • A redacted request body if the issue reproduces consistently.