If you've ever used Stripe's API, you've experienced a clever pattern: test keys and live keys both hit the same API endpoint, but they route to completely different backends. Your sandbox requests never touch production data, and you don't need to remember separate URLs for each environment.
It's called environment-based routing, and in this post we're going to show you how to implement it using TypeScript and the awesome programmable aspects of the Zuplo API Gateway.
- Building an API with separate sandbox and production environments
- Need to route customers to isolated backends for compliance or data residency
- Want a single API endpoint that serves both shared and dedicated infrastructure
- Looking to implement Stripe-style test/live key patterns
What is Environment-Based Routing?
Environment-based routing lets you direct API requests to different backend systems based on metadata attached to the caller's identity. Instead of exposing separate endpoints for sandbox vs. production (or different customer environments), you expose a single API URL. The gateway reads the caller's API key metadata or JWT claims and routes the request to the appropriate backend.
This creates a cleaner developer experience. Your API consumers don't need to manage multiple base URLs or remember which environment they're targeting. The key itself carries that context.
Why Use Environment-Based Routing?
There are three common scenarios where this pattern makes sense to use:
Sandbox/Production Separation
The Stripe model. Give developers a test key for development and a live key for production. Both keys work against your single API endpoint, but test keys route to sandbox infrastructure with mock data, while live keys route to production systems with real data. Developers can safely test integrations without worrying about affecting production.
Customer Isolation
For B2B APIs with compliance or data residency requirements, you might need to route each customer to their own isolated backend. A healthcare API might route Customer A's requests to their dedicated HIPAA-compliant infrastructure while Customer B routes to a separate isolated environment. The API surface looks identical; only the underlying backend differs.
Hybrid Multi-Tenant Architecture
Maybe most of your customers share a multi-tenant backend, but your enterprise customers pay for dedicated infrastructure. Environment-based routing lets you handle both cases through the same API endpoint. Standard customers route to shared infrastructure; premium customers route to their dedicated environment.
How Zuplo Implements This
Zuplo's programmable gateway makes this straightforward. When a request is
authenticated (via API key or JWT), user information becomes available on
request.user. This includes metadata you've attached to the API key or custom
claims from the JWT.
A custom inbound policy reads this metadata and sets the backend URL dynamically:
The URL Rewrite handler then uses context.custom.downstreamUrl to forward the
request to the correct backend. The caller never sees which backend handled
their request; they just get the appropriate response.
To set this up, you attach metadata to your API keys when creating them. You can do this in the Zuplo portal for testing, or programmatically via the Zuplo API when provisioning keys for your users:
Or for production keys:
The same pattern works with JWT authentication. Just include the environment (or
customer ID, or tenant info) as a custom claim, and your routing policy reads it
from request.user.data.
Benefits
This approach gives you a single entry point for all your customers. Documentation, SDKs, and client implementations stay simple because there's one URL to remember.
Policy enforcement happens uniformly at the gateway. Authentication, rate limiting, and other policies apply consistently before requests reach any backend. This ensures security and compliance across all environments without duplicating configuration.
And because Zuplo policies are just TypeScript, you can implement whatever routing logic you need: geographic routing, A/B testing, failover handling, or combinations of multiple factors.
Try It Yourself
We've published a complete working example that implements Stripe-style environment routing. The example includes mock backends, pre-configured policies, and step-by-step instructions for creating API keys with environment metadata.
Environment-Based Routing Example
A complete working example that implements Stripe-style environment routing with API key metadata. Run locally or deploy directly to your Zuplo account.
For the full implementation guide covering additional patterns like customer-specific routing and hybrid multi-tenant architectures, see our documentation.