Apigee Edge is winding down. The final Private Cloud (OPDK) version, 4.53.01, reaches end of life on February 26, 2027. The Classic UI shut down on November 2, 2025. Public Cloud customers are getting increasingly urgent migration notices. If you’re running APIs on Apigee Edge, the question isn’t whether to migrate — it’s where.
Google’s recommended path is Apigee X, but that migration is notoriously complex. Apigee X is not an in-place upgrade — it’s a different platform with different infrastructure, APIs, and deployment models. SADA, a Google Cloud partner, describes the Edge-to-X migration as “a daunting task that requires lots of careful planning, scripting, testing, and coordination.”
This guide walks you through migrating from Apigee to Zuplo — mapping every policy, translating architecture concepts, and cutting over with zero downtime. For the business case behind this move, see our companion post on Apigee Edge reaching end of life.
What This Guide Covers
- Architecture Comparison
- Policy-to-Policy Mapping
- Complete Policy Reference
- Developer Portal Migration
- API Product and App Migration
- Step-by-Step Migration Process
- Handling Custom Apigee Policies
- Analytics and Monitoring Migration
- Common Migration Pitfalls
- Post-Migration Optimization
Architecture Comparison
Before diving into policy mapping, it helps to understand how Apigee and Zuplo differ architecturally. The two platforms share the same goal — managing API traffic — but take fundamentally different approaches.
Apigee’s Architecture
Apigee uses a proxy + target model. You define API proxies that intercept client requests, apply policies (written in XML), and forward traffic to target endpoints. Configuration is split across proxy bundles, shared flows, target servers, environment configurations, and key-value maps. Deployment is region-bound — tied to Google Cloud Platform in the case of Apigee X, or to your own infrastructure for Private Cloud.
Custom logic lives in JavaScript callouts (running on a proprietary runtime), Java callouts (compiled JAR files deployed with your proxy bundle), or Python scripts (limited support). Apigee’s Trireme-based Node.js runtime already reached end of life, further limiting options.
Zuplo’s Architecture
Zuplo is an edge-native, programmable API gateway. Your API configuration is
a standard OpenAPI document (routes.oas.json) extended with Zuplo-specific
annotations. Policies are defined declaratively in policies.json and executed
in a pipeline — inbound policies run before the request reaches your backend,
outbound policies run before the response reaches the client.
Custom logic is written in TypeScript and runs on a Web Standards-based
runtime (standard Request, Response, and fetch APIs). Everything lives in
Git — routes, policies, custom code, environment variables, and developer portal
configuration. Push to main and your gateway deploys globally across
300+ edge locations in under
20 seconds.
Key Architectural Differences
- Configuration format: Apigee uses XML policy bundles. Zuplo uses JSON (OpenAPI + policies) and TypeScript.
- Deployment model: Apigee is region-bound (GCP for Apigee X). Zuplo deploys to 300+ global edge locations on any cloud.
- Custom logic runtime: Apigee uses proprietary JavaScript/Java callouts. Zuplo uses standard TypeScript with Web APIs.
- Configuration management: Apigee requires custom CI/CD tooling. Zuplo is GitOps-native — push to Git and it deploys.
- Developer portal: Apigee uses a separate Drupal-based portal. Zuplo auto-generates a portal from your OpenAPI spec.
Policy-to-Policy Mapping
This is the core of any Apigee migration. Every Apigee policy has a Zuplo equivalent — either a built-in policy, a configuration option, or a short TypeScript module.
Traffic Management Policies
SpikeArrest → Rate Limiting
Apigee’s SpikeArrest policy smooths traffic spikes by limiting the peak request rate. In Zuplo, the rate-limit-inbound policy provides equivalent functionality with more flexibility — you can limit by IP, authenticated user, API key, or a custom function.
Quota → Rate Limiting (per-user)
Apigee’s Quota policy enforces long-term usage limits per developer or app. In
Zuplo, you use the same rate-limit-inbound policy with rateLimitBy set to
"user" or "function" for per-consumer tier limits.
Authentication Policies
VerifyAPIKey → API Key Authentication
Apigee’s VerifyAPIKey policy validates API keys sent as query parameters or headers. Zuplo’s api-key-inbound policy does the same, backed by a globally distributed API key service.
OAuthV2 (VerifyAccessToken) → JWT Authentication
Apigee’s OAuthV2 policy with the VerifyAccessToken operation validates OAuth
2.0 bearer tokens. In Zuplo, the
open-id-jwt-auth-inbound
policy validates JWTs from any OpenID-compliant provider. Zuplo also offers
provider-specific policies for
Auth0,
Okta,
Clerk,
Supabase,
AWS Cognito, and
Firebase.
BasicAuthentication → Basic Auth
Apigee’s BasicAuthentication policy decodes Base64-encoded credentials. Zuplo’s
basic-auth-inbound policy provides the same functionality.
Message Transformation Policies
AssignMessage → Header / Body / Query Param Policies
Apigee’s AssignMessage is a multipurpose policy for setting headers, query parameters, form parameters, and the request body. In Zuplo, these capabilities are split into focused policies:
- Set headers → set-headers-inbound
- Remove headers → remove-headers-inbound
- Set query parameters → set-query-params-inbound
- Set request body → set-body-inbound
XMLToJSON / JSONToXML → XML to JSON Outbound
Apigee’s format conversion policies have a direct equivalent in Zuplo’s xml-to-json-outbound policy, which is especially useful for modernizing legacy SOAP backends.
ExtractVariables → Custom Code
Apigee’s ExtractVariables policy parses variables from request/response payloads
using JSON paths, XML paths, or regex. In Zuplo, you handle this with a
custom-code-inbound
policy — a TypeScript function that extracts values and stores them on
context.custom for downstream policies to use.
Mediation Policies
RaiseFault → Custom Code (return Response)
Apigee’s RaiseFault policy generates custom error responses. In Zuplo, any
inbound policy can short-circuit the pipeline by returning a Response object:
ServiceCallout → fetch() in Custom Code
Apigee’s ServiceCallout policy makes HTTP requests to external services during
the proxy flow. In Zuplo, you use the standard fetch() API inside a custom
code policy:
Routing and Target Policies
RouteRules / TargetEndpoint → URL Forward or URL Rewrite Handler
Apigee’s proxy-to-target routing is handled by Zuplo’s URL Forward Handler (appends the incoming path to a base URL) or URL Rewrite Handler (rewrites URLs using template interpolation).
Security Policies
AccessControl → ACL Policy
Apigee’s AccessControl policy restricts access by IP address. Zuplo’s
acl-policy-inbound policy provides similar IP-based access control.
MessageValidation → Request Validation
Apigee’s message validation policies (SOAPMessageValidation, JSONThreatProtection, XMLThreatProtection) map to Zuplo’s request-validation-inbound policy, which validates requests against your OpenAPI schema definitions — including body, query parameters, path parameters, and headers.
Complete Policy Reference
Here is a quick-reference mapping of the most common Apigee policies to their Zuplo equivalents:
- SpikeArrest →
rate-limit-inbound - Quota →
rate-limit-inbound(withrateLimitBy: "user"or"function") - VerifyAPIKey →
api-key-inbound - OAuthV2 (VerifyAccessToken) →
open-id-jwt-auth-inbound(or provider-specific JWT policies) - BasicAuthentication →
basic-auth-inbound - AssignMessage (headers) →
set-headers-inbound/remove-headers-inbound - AssignMessage (query params) →
set-query-params-inbound - AssignMessage (body) →
set-body-inbound - XMLToJSON →
xml-to-json-outbound - ExtractVariables →
custom-code-inbound(TypeScript) - JavaScript / JavaCallout →
custom-code-inbound/custom-code-outbound(TypeScript) - ServiceCallout →
custom-code-inboundwithfetch() - RaiseFault → Return a
Responsefrom any custom policy - AccessControl →
acl-policy-inbound - JSONThreatProtection →
request-validation-inbound - ResponseCache → Handled at the edge automatically, or via custom code
- KeyValueMapOperations → Environment variables +
context.custom - FlowCallout (Shared Flows) → Composite policies (
composite-inbound/composite-outbound)
Developer Portal Migration
Apigee’s developer portal is typically Drupal-based — requiring separate hosting, CMS management, theme customization, and manual content updates. Many teams have invested significant effort in customizing their Drupal portal with custom themes, documentation pages, and interactive features.
Zuplo takes a fundamentally different approach. Your
developer portal is
auto-generated directly from your OpenAPI spec. Every route, parameter, and
schema you define in routes.oas.json automatically appears in your portal
with:
- Interactive API documentation — auto-generated from your OpenAPI spec, always in sync with your gateway configuration
- API Playground — developers can test live endpoints directly from the portal
- Self-serve API key management — developers sign up, create keys, and manage their own access without admin intervention
- Custom pages — add rich documentation with MDX (Markdown + JSX components)
- Custom themes — full visual customization with Tailwind CSS and shadcn themes
- Custom domains — host your portal on
docs.yourcompany.com
Migration Steps for Your Developer Portal
- Export your OpenAPI specs from Apigee — use the Apigee management API or download from the Apigee UI
- Import into Zuplo — your specs become both your gateway configuration and your portal documentation
- Add custom documentation — migrate any guides, tutorials, or reference pages from Drupal to MDX custom pages in Zuplo
- Configure authentication — set up developer sign-in using Auth0, Clerk, Supabase, or any OAuth provider
- Update DNS — point your developer portal domain to Zuplo
The biggest win here is eliminating the Drupal dependency entirely. No more CMS upgrades, no more theme compatibility issues, no more manually syncing API documentation with your actual API behavior.
API Product and App Migration
Apigee uses a hierarchy of API Products, Developer Apps, and API Keys to control access. Here’s how these concepts translate to Zuplo:
Apigee API Products → Zuplo Routes + Policies
In Apigee, an API Product bundles specific API proxy paths with quota limits and OAuth scopes. In Zuplo, you achieve this by:
- Defining routes in your OpenAPI spec (
routes.oas.json) - Attaching policies (rate limiting, authentication) per route
- Using consumer metadata to control per-consumer access levels
Apigee Developer Apps → Zuplo Consumers
In Apigee, a Developer App represents an application registered by a developer, with one or more API keys. In Zuplo, consumers serve the same purpose:
- Each consumer represents a person, organization, or service
- Consumers can have one or more API keys
- Consumers carry metadata (plan tier, organization name, custom attributes)
accessible at runtime via
request.user.data - Consumers can be tagged for grouping and management
Migrating API Keys
If you need to migrate existing API keys from Apigee (to avoid breaking existing integrations during the transition), you can use Zuplo’s Developer API to programmatically create consumers and import keys. A typical migration script would:
- Export developer apps and keys from Apigee’s management API
- Create corresponding consumers in Zuplo with matching metadata
- Import the API keys so existing client integrations continue working
- Run both gateways in parallel during the transition period
Step-by-Step Migration Process
Phase 1: Pre-Migration Audit
Before touching any configuration, inventory everything your Apigee setup does.
Routes and proxies:
- List every API proxy and its base path
- Document all route rules and target endpoint configurations
- Identify conditional flows and their conditions
- Note any shared flows referenced across proxies
Policies:
- Catalog every policy by type (security, mediation, traffic management)
- Document policy execution order in PreFlow, conditional flows, and PostFlow
- Note any custom JavaScript or Java callouts
- Identify policies with environment-specific configurations
External dependencies:
- List all target servers and their configurations
- Document key-value map entries and their usage
- Identify service callout endpoints
- Note any encrypted KVM entries (secrets)
Developer ecosystem:
- Count active developer apps and API keys
- Document API product configurations and quota limits
- Export developer portal customizations and custom pages
- List custom attributes on developers and apps
Phase 2: Set Up Zuplo
- Create your Zuplo project — sign up at portal.zuplo.com and create a new project
- Connect to Git — link your project to a GitHub repository for GitOps-based deployments
- Import your OpenAPI specs — use the OpenAPI import to bootstrap your route configuration
- Configure policies — add authentication, rate limiting, and transformation policies to each route using the policy mapping table above
- Add custom logic — rewrite any JavaScript or Java callouts as TypeScript
modules in the
modules/directory - Set environment variables — migrate Apigee KVM entries and target server URLs to Zuplo environment variables
Phase 3: Parallel Running
Run Zuplo alongside Apigee to validate behavior before cutting over:
- Deploy to a preview environment — every Git branch gets its own isolated Zuplo environment with a unique URL
- Run your test suite against Zuplo — point integration tests at the preview URL
- Compare responses — verify that Zuplo returns identical responses for the same requests
- Load test — confirm that Zuplo handles your peak traffic patterns
Phase 4: Traffic Cutover
Use one of these strategies for a zero-downtime cutover:
DNS-based blue-green deployment:
- Lower your API domain’s DNS TTL to 60 seconds (24 hours before cutover)
- Switch DNS to point at Zuplo’s edge network
- Monitor error rates and latency
- Roll back by reverting DNS if anything goes wrong
Canary routing (percentage-based):
- Route 5% of traffic to Zuplo while 95% continues through Apigee
- Monitor for errors and latency differences
- Gradually increase to 25%, then 50%, then 100%
- This approach gives you fine-grained control and easy rollback
For more detail on zero-downtime strategies, see our guide to migrating from self-hosted to managed API gateways.
Phase 5: Validation and Cleanup
After full cutover:
- Verify all routes return expected response codes
- Confirm authentication works for all methods
- Validate rate limiting triggers at correct thresholds
- Check that logs flow to your monitoring system
- Decommission Apigee proxies and infrastructure
Handling Custom Apigee Policies
Custom logic is where most Apigee migrations stall. If you’ve invested in JavaScript callouts, Java callouts, or Python scripts, you’ll need to rewrite them. The good news: TypeScript is a significant upgrade in every dimension.
JavaScript Callouts → TypeScript Policies
Apigee JavaScript callouts use a proprietary runtime with Apigee-specific
objects (context, proxyRequest, proxyResponse). Zuplo uses standard Web
APIs — Request, Response, Headers, fetch — that any TypeScript developer
already knows.
Apigee JavaScript callout:
Zuplo TypeScript equivalent:
Java Callouts → TypeScript Modules
Java callouts are the heaviest lift in an Apigee migration. Apigee lets you deploy compiled JAR files that run complex business logic — encryption, third-party SDK integrations, data transformations.
In Zuplo, you replace Java callouts with TypeScript modules. For most use cases
this is straightforward — TypeScript has excellent ecosystem support for
cryptography (crypto Web API), HTTP clients (fetch), and data
transformation. For cases where you need a specific Java library, consider:
- npm equivalents — most Java libraries have TypeScript/JavaScript alternatives on npm
- External microservice — extract complex Java logic into a standalone
service and call it via
fetch()from your Zuplo policy - WebAssembly — for compute-intensive operations, compile your Java code (or rewrite in Rust/Go) to Wasm
Shared Flows → Composite Policies
Apigee’s shared flows let you define reusable policy sequences that can be called from multiple API proxies via FlowCallout. Zuplo’s equivalent is composite policies — group multiple policies into a single named policy that can be attached to any route:
This lets you define your “standard security stack” once and apply it consistently across all routes, just like shared flows in Apigee.
Analytics and Monitoring Migration
Apigee includes built-in analytics with dashboards for traffic, error rates, latency, and developer engagement. Migrating your observability setup requires understanding Zuplo’s analytics model and integrating with your existing monitoring stack.
Built-in Analytics
Zuplo provides built-in analytics dashboards covering request volumes, error rates, latency percentiles, and per-API-key usage. For most teams, this provides immediate visibility without additional configuration.
Integrating with Your Existing Monitoring Stack
If you’re using third-party monitoring tools with Apigee, Zuplo supports direct integrations through logging and metrics plugins:
- Datadog — stream logs and metrics directly from Zuplo
- New Relic — real-time log and metrics forwarding
- Google Cloud Logging — if you’re keeping some GCP infrastructure, Zuplo integrates directly
- Splunk — log streaming for enterprise SIEM workflows
- Dynatrace — full observability integration
- OpenTelemetry — export traces and logs to any OTLP-compatible backend (Honeycomb, Jaeger, and more)
These integrations are configured in your zuplo.runtime.ts file — a TypeScript
module that runs at startup:
Custom Logging
Every request in Zuplo is logged with structured data including the API key,
route, response code, latency, and request ID. You can add custom attributes
using context.log in any policy or handler:
Common Migration Pitfalls
Forgetting About Shared Flows
The mistake: You migrate individual API proxies but forget that they depend on shared flows for authentication, logging, or error handling.
The fix: Before migrating any proxy, trace its full execution path including all FlowCallout references. Create composite policies in Zuplo that replicate the shared flow behavior, then attach them to the appropriate routes.
Overlooking Environment-Specific Configuration
The mistake: Apigee’s environment configurations (target servers, KVM entries, resource files) vary between dev, staging, and production. You migrate the production config but forget the environment-specific differences.
The fix: Zuplo handles this with environment variables scoped per environment type. Map each Apigee KVM entry and target server URL to a Zuplo environment variable, and set different values for production vs. preview environments.
Ignoring Conditional Flow Logic
The mistake: Apigee’s conditional flows execute different policy sequences based on request attributes (path suffix, HTTP verb, headers). You migrate the policies but not the conditions.
The fix: In Zuplo, conditional logic is handled either by defining separate routes (each with its own policy set) or by implementing conditions inside a custom code policy. Most Apigee conditional flows map naturally to separate route definitions in your OpenAPI spec.
Big-Bang Migration
The mistake: Migrating all API proxies at once on a single cutover date.
The fix: Migrate proxy by proxy, starting with low-traffic, low-risk endpoints. Use canary routing to validate each batch before moving to the next. This limits blast radius and gives you confidence with each step.
Not Testing Under Real Load
The mistake: Your integration tests pass, so you assume production will work.
The fix: Use shadow traffic testing or replay production access logs against Zuplo. Synthetic tests don’t catch the edge cases that real traffic exposes — unusual header combinations, oversized payloads, concurrent requests from the same client.
Post-Migration Optimization
Once you’ve completed the migration, take advantage of Zuplo features that Apigee didn’t offer:
Edge Deployment
Your APIs now run at 300+ edge locations globally. Requests are automatically routed to the nearest point of presence, reducing latency for users everywhere — not just in the GCP regions where Apigee was deployed.
GitOps Workflow
Every change to your API gateway is a Git commit. Open a pull request and get an isolated preview environment automatically. Review policy changes in code review, just like application code. Roll back by reverting a commit. This is a fundamentally better workflow than Apigee’s UI-driven or script-based deployment model.
OpenAPI-First Development
Your routes.oas.json file is both your gateway configuration and your API
documentation source. Changes to routes automatically update your developer
portal. No more manually syncing documentation with behavior.
API Monetization
If you’re migrating monetized APIs, Zuplo offers built-in monetization with usage-based billing integrations. Instead of building custom metering on top of Apigee, you get native support for tracking usage, enforcing plan limits, and integrating with billing platforms like Stripe.
TypeScript Ecosystem
With Zuplo, your gateway logic is standard TypeScript. You can use any npm package, share code between your API gateway and your application, and leverage the full TypeScript ecosystem for testing, linting, and type checking.
Next Steps
You now have a complete map from Apigee to Zuplo: every major policy has a direct equivalent, the developer portal migration eliminates your Drupal dependency, and the phased cutover approach keeps production traffic safe throughout. The most common blockers — shared flows, environment-specific KVM entries, and Java callouts — each have a clear TypeScript-based solution.
Migrating from Apigee is a significant project, but it pays dividends in reduced complexity, better developer experience, and lower costs. The key is to approach it methodically — inventory everything, map policies, migrate incrementally, and validate thoroughly.
For a high-level comparison of Apigee and Zuplo features, see the Apigee alternative comparison page. For guidance on migration strategies and zero-downtime patterns, see our guide to migrating from self-hosted to managed API gateways.
Ready to migrate? Start a free Zuplo project and import your first API proxy in minutes — no credit card required.