ZuploZuplo
LoginSign Up
  • Documentation
  • API Reference
Introduction
Getting Started
    Develop using the Portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingMCP - Quick start
    Develop Locally
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth
Concepts
Development
Policies
Handlers
API Keys
MCP Server
MCP Gateway
AI Gateway
Developer Portal
Monetization
Deploying & Source Control
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
    Migration OverviewMigrate from KongMigrate from ApigeeMigrate from AWS API GatewayMigrate from Azure APIM
Platform LimitsSecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Migration Guides

Migrate from Azure API Management to Zuplo

This guide walks through migrating from Azure API Management (APIM) to Zuplo. It covers the key differences, concept mapping, policy translation, and a step-by-step migration process.

Why teams migrate from Azure APIM

Azure API Management is a natural choice for organizations running on Microsoft Azure. However, teams frequently encounter friction points that prompt them to evaluate alternatives:

  • Slow deployments — Azure APIM deployments can take 15-45 minutes to propagate, creating long feedback loops during development. Creating a new APIM instance can take 30-60 minutes.
  • Expensive per-environment pricing — Each APIM instance (dev, staging, production) is billed separately. The Developer tier starts at ~$50/month, but the Standard tier needed for production starts at ~$700/month per instance.
  • Poor GitOps support — Azure APIM uses ARM templates, Bicep, or Terraform for infrastructure-as-code, but the policy definitions are embedded XML that does not merge well in version control.
  • XML policy complexity — Like Apigee, Azure APIM policies are written in XML with C# expressions. The syntax is verbose and error-prone, especially for complex transformations.
  • Azure lock-in — APIM is tightly integrated with the Azure ecosystem. Using it with non-Azure backends or multi-cloud architectures adds friction.
  • Limited developer portal customization — The built-in developer portal has improved over time but still requires significant effort to customize and lacks features like self-serve API key management with built-in billing.

Imburse Payments, a UK fintech, chose Zuplo over Azure API Management to optimize the API experience for their customers and improve their engineering team's workflow.

Concept mapping: Azure APIM to Zuplo

Azure APIM conceptZuplo equivalent
APIRoutes in your OpenAPI spec
OperationRoute (path + method) in OpenAPI spec
BackendURL Forward handler target
Inbound policy (XML)Inbound policy (TypeScript)
Outbound policy (XML)Outbound policy (TypeScript)
Named valueEnvironment variable
Subscription keyAPI Key Authentication
ProductAPI key with metadata
Service (APIM instance)Environment
Developer portalZuplo Developer Portal
Application InsightsLogging integrations (Datadog, Splunk, etc.)
API revisionGit branch with branch-based deployment
Gateway (self-hosted)Self-hosted Zuplo

Step-by-step migration

Step 1: Export your API definition

Azure APIM stores API definitions as OpenAPI specs. Export them:

Using the Azure Portal:

  1. Navigate to your APIM instance.
  2. Select APIs from the sidebar.
  3. Select the API you want to export.
  4. Click the ... menu and select Export.
  5. Choose OpenAPI v3 (JSON).

Using the Azure CLI:

TerminalCode
az apim api export \ --resource-group myResourceGroup \ --service-name myApimService \ --api-id my-api \ --export-format openapi-link

Step 2: Map Azure APIM policies to Zuplo policies

The following table maps common Azure APIM policies to Zuplo equivalents:

Azure APIM policyZuplo policy
check-headerCustom Code Policy checking headers
set-headerSet Headers
remove-headerRemove Headers
set-bodySet Body
set-query-parameterSet Query Params
rewrite-uriURL Rewrite handler
rate-limit / rate-limit-by-keyRate Limiting
quota / quota-by-keyQuota
validate-jwtOpen ID JWT Authentication
authentication-basicBasic Authentication
ip-filterIP Restriction
corsBuilt-in CORS configuration
json-to-xml / xml-to-jsonXML to JSON or custom code
find-and-replaceReplace String
cache-lookup / cache-storeCaching
mock-responseMock API
Custom C# expressionCustom Code Policy (TypeScript)

Step 3: Translate policy configuration

Here is an example of translating an Azure APIM rate limit policy to a Zuplo rate limit policy.

Azure APIM XML policy:

XMLCode
<policies> <inbound> <rate-limit-by-key calls="100" renewal-period="60" counter-key="@(context.Subscription.Id)" /> <set-header name="X-Request-Id" exists-action="skip"> <value>@(Guid.NewGuid().ToString())</value> </set-header> </inbound> </policies>

Zuplo policy configuration:

Code
{ "policies": { "inbound": [ { "name": "rate-limit-inbound", "policyType": "rate-limit-inbound", "handler": { "export": "RateLimitInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "rateLimitBy": "user", "requestsAllowed": 100, "timeWindowMinutes": 1 } } }, { "name": "set-request-id", "policyType": "set-headers-inbound", "handler": { "export": "SetHeadersInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "headers": [ { "name": "X-Request-Id", "value": "$function(generateId)", "overwrite": false } ] } } } ] } }

Step 4: Translate C# policy expressions to TypeScript

Azure APIM allows inline C# expressions in XML policies. Translate these to TypeScript custom code policies.

Azure APIM C# expression:

XMLCode
<policies> <inbound> <set-header name="X-Forwarded-For" exists-action="override"> <value>@(context.Request.IpAddress)</value> </set-header> <choose> <when condition="@(context.Request.Headers .GetValueOrDefault("Authorization","") .Length == 0)"> <return-response> <set-status code="401" reason="Unauthorized" /> <set-body>{"error": "Missing authorization"}</set-body> </return-response> </when> </choose> </inbound> </policies>

Equivalent Zuplo TypeScript policy:

Code
import { ZuploContext, ZuploRequest, HttpProblems } from "@zuplo/runtime"; export default async function ( request: ZuploRequest, context: ZuploContext, options: never, policyName: string, ) { const authHeader = request.headers.get("authorization"); if (!authHeader) { return HttpProblems.unauthorized(request, context, { detail: "Missing authorization", }); } // Forward the client IP const headers = new Headers(request.headers); headers.set("X-Forwarded-For", request.headers.get("x-real-ip") ?? ""); return new ZuploRequest(request, { headers }); }

Step 5: Migrate subscription keys to Zuplo API keys

Azure APIM uses subscription keys tied to products. Migrate to Zuplo's API key system:

Azure APIM subscription featureZuplo equivalent
Subscription keyAPI key
Product groupingAPI key metadata for access control
Subscription approvalAPI key creation via Portal or API
Key regenerationKey rotation in the Zuplo Portal or Developer Portal
Usage reportingBuilt-in analytics and logging integrations

Step 6: Migrate named values to environment variables

Azure APIM named values become Zuplo environment variables:

Azure APIM named value typeZuplo equivalent
Plain valueEnvironment variable
Secret valueSecret environment variable
Key Vault referenceSecret environment variable

Access environment variables in route configuration using $env(VARIABLE_NAME) or in custom code using context.env.VARIABLE_NAME.

Step 7: Deploy and migrate traffic

  1. Deploy your Zuplo project by pushing to your connected Git repository.
  2. Set up a custom domain for Zuplo.
  3. Route a subset of traffic to Zuplo using Azure Front Door, Traffic Manager, or DNS-based routing.
  4. Validate behavior matches your Azure APIM configuration.
  5. Gradually shift all traffic to Zuplo.
  6. Decommission your Azure APIM instances.

Keeping Azure backends with Zuplo

You do not need to migrate your backend infrastructure. Zuplo works with any HTTP backend, including:

  • Azure App Service
  • Azure Functions
  • Azure Kubernetes Service (AKS)
  • Azure Container Apps
  • Any Azure service with an HTTP endpoint

Use backend security options to secure the connection between Zuplo and your Azure backends.

Deployment model comparison

FeatureAzure APIMZuplo
Deployment time15-45 minutesUnder 20 seconds
New instance creation30-60 minutesInstant
Environment cost~$700/month per Standard instanceFree tier available; environments are free
Preview environmentsManual setup requiredAutomatic per Git branch
Global distributionPremium tier + multi-region configBuilt-in across 300+ edge locations
GitOps workflowARM/Bicep + XML policiesOpenAPI + TypeScript, native Git integration

Next steps

  • Set up your first Zuplo gateway
  • Add rate limiting
  • Add API key authentication
  • Configure your developer portal
  • Set up source control
Edit this page
Last modified on March 25, 2026
Migrate from AWS API GatewayPlatform Limits
On this page
  • Why teams migrate from Azure APIM
  • Concept mapping: Azure APIM to Zuplo
  • Step-by-step migration
    • Step 1: Export your API definition
    • Step 2: Map Azure APIM policies to Zuplo policies
    • Step 3: Translate policy configuration
    • Step 4: Translate C# policy expressions to TypeScript
    • Step 5: Migrate subscription keys to Zuplo API keys
    • Step 6: Migrate named values to environment variables
    • Step 7: Deploy and migrate traffic
  • Keeping Azure backends with Zuplo
  • Deployment model comparison
  • Next steps
JSON
TypeScript