Skip to main content
You’re already calling OpenAI, Anthropic, Bedrock, etc. from your application. You want to add governance, budgets, fallback, policy-rule patterns, per-engineer attribution, without rewriting everything. This cookbook shows the minimum-effort migration.

Before

After

Two env-var changes. That’s the whole code migration if you’re happy with default gateway behaviour (no budget, cache-respect, fallback disabled). Read on for the policy additions.

Pre-migration checklist

  • LangWatch project provisioned (you already have one for tracing, reuse it).
  • API token with modelProviders:update + virtualKeys:create at the same ORGANIZATION scope. Use the LangWatch UI → Settings → API Tokens.
  • Access to the upstream provider accounts (you’ll rebind their existing keys inside LangWatch).

Step 1: Configure the providers you already use

For each provider (OpenAI, Anthropic, Bedrock, Azure, Vertex, Gemini) configure (or reuse) a ModelProvider at the organization scope. In the UI: Settings → Model Providers → Add Model Provider. Pick Scope = Organization so every project in the org inherits the credential. Then open each row and switch to the Advanced (Gateway) tab to set the gateway-only fields:
  • Rate limit (RPM / TPM / RPD) — caps the gateway applies before dispatch.
  • Fallback priority — used when the org’s default RoutingPolicy resolves more than one eligible MP (lower wins; tiebreak by createdAt).
  • Provider config (JSON) — region/deployment overrides (e.g. {"region": "us-east-1"}).
No separate “gateway provider” entity to mint. The credential itself is the only thing.
If you’ve never configured ModelProviders in LangWatch before, this is the same Settings page you’d use for prompt playground + evaluators — the gateway just reads from the same store.

Step 2: Mint your first virtual key

Save the secret. It’s shown exactly once. The VK lives at ORG:acme and inherits every ModelProvider visible from that scope. To pin a specific provider order, create a RoutingPolicy and pass --routing-policy <id>; otherwise the org’s default ordering applies.

Step 3: Flip the env vars in your app

Dev/staging first:
Redeploy. Every request now flows through the gateway.

Verify the migration is live

You should see X-LangWatch-Request-Id, X-LangWatch-Trace-Id, X-LangWatch-Span-Id. Paste the request id into the LangWatch search bar, the full trace is already there.

Step 4: Add your first policy

The whole point of the migration. Pick the policy that maps to a real pain you have today:

Hard cap on engineering spend

Every VK attached to engineering principals now shares the $5K/month envelope.

Automatic failover when OpenAI is flaky

Create a RoutingPolicy listing the ModelProvider ids in dispatch order (OpenAI primary, Anthropic backup), then point the VK at it:
When OpenAI throws a 503, the gateway re-dispatches the same prompt to Anthropic transparently. Your application sees a normal 200 response. Tune the fallback conditions (5xx / timeout / rate_limit / network_error) via the VK --config-json field; the model_aliases map still lives there for client-side name redirects.

Block destructive tools on engineer VKs

Agent calls like shell.exec("rm -rf ~") get 403 tool_not_allowed before they reach the model, the model never generates the destructive call path in the first place.

Step 5: Wire trace propagation

If you were already using LangWatch SDKs for tracing, propagate the trace id into the gateway so requests nest under your existing trace (no double-cost-attribution):
See Python SDK → trace propagation and TypeScript SDK.

Step 6: Rotate the original upstream keys

After a week of running through the gateway, the original upstream keys (sk-proj-..., sk-ant-...) should no longer be used by any application. Rotate them in the provider console, this is the only time you need to touch upstream again. The gateway still has access via its own encrypted copies of the old keys (fetched from the LangWatch control plane), and will continue to serve traffic uninterrupted.

Troubleshooting

What NOT to change

  • Request bodies: the gateway’s whole point is byte-for-byte passthrough. Don’t rewrite your payloads.
  • SDKs: the official OpenAI, Anthropic SDKs work unchanged. You don’t need the LangWatch SDK for gateway integration (only for trace propagation).
  • Streaming handlers: SSE passthrough is byte-identical post-first-chunk. Your streaming code should keep working.

Rollback plan

If the gateway misbehaves, flip the env vars back:
Redeploy. You’re back to direct provider calls. Traces in LangWatch stop populating (the trace propagation + gateway spans go away), but your app works. Plan the first rollout behind a feature flag for this exact reason, 10% traffic through the gateway for a day before going 100%.

See also