Skip to content

Azure API Management

First PublishedByAtif Alam

Azure API Management (APIM) is a fully managed API gateway that sits in front of your backend APIs. It handles authentication, rate limiting, caching, transformation, monitoring, and developer documentation — so your backend services focus on business logic.

Without a gateway, every backend service handles its own:

  • Authentication and authorization
  • Rate limiting and throttling
  • Request/response transformation
  • Monitoring and logging
  • API versioning

An API gateway centralizes these concerns:

Clients (mobile, web, partners)
Azure API Management
├── Authentication (OAuth 2.0, API keys, JWT)
├── Rate limiting / throttling
├── Caching
├── Request transformation
├── Monitoring / analytics
├──► Backend: Order Service
├──► Backend: Product Service
├──► Backend: User Service
└──► Backend: Azure Function
ComponentWhat It Does
GatewayReceives API calls, applies policies, routes to backends
Management planeConfigure APIs, products, policies (portal or ARM)
Developer portalAuto-generated API documentation for consumers
AnalyticsUsage metrics, error rates, latency
Product: "Free Tier" (rate limit: 100 calls/min)
└── API: Orders API (v1)
├── Operation: GET /orders
├── Operation: POST /orders
└── Operation: GET /orders/{id}
Product: "Premium" (rate limit: 10,000 calls/min)
├── API: Orders API (v1)
└── API: Analytics API (v2)
ConceptDescription
APIA set of operations that map to a backend service
OperationA single HTTP method + path (e.g. GET /orders)
ProductGroups APIs with usage policies (subscriptions, rate limits)
SubscriptionAn API key that grants access to a product
PolicyXML rules applied at various scopes (inbound, backend, outbound, on-error)
Terminal window
# Create an API Management instance (Developer tier for testing)
az apim create \
--resource-group myapp-rg \
--name myapp-api \
--publisher-name "My Company" \
--publisher-email "[email protected]" \
--sku-name Developer \
--location eastus
TierUse CaseSLAGateway CapacityCost
ConsumptionServerless, pay-per-call99.95%Auto-scale~$3.50 per 10K calls
DeveloperTesting and developmentNo SLA1 unit~$50/month
BasicSmall production99.95%Up to 2 units~$150/month
StandardMedium production99.95%Up to 4 units~$700/month
PremiumEnterprise, multi-region99.99%Up to 12+ units~$2,800/month
Terminal window
# Import from an OpenAPI/Swagger file
az apim api import \
--resource-group myapp-rg \
--service-name myapp-api \
--path "orders" \
--specification-format OpenApi \
--specification-url "https://myapp.azurewebsites.net/swagger/v1/swagger.json" \
--display-name "Orders API" \
--api-id "orders-api"
Terminal window
az apim api import \
--resource-group myapp-rg \
--service-name myapp-api \
--path "functions" \
--specification-format OpenApi \
--specification-url "https://my-func-app.azurewebsites.net/api/swagger.json" \
--display-name "Functions API"

APIM can also import from Azure App Service, Logic Apps, or manually defined operations.

Policies are XML rules that transform requests and responses at four stages:

<policies>
<inbound>
<!-- Applied before the request reaches the backend -->
</inbound>
<backend>
<!-- Applied just before forwarding to the backend -->
</backend>
<outbound>
<!-- Applied to the response before sending to the client -->
</outbound>
<on-error>
<!-- Applied when an error occurs at any stage -->
</on-error>
</policies>
<inbound>
<!-- 100 calls per 60 seconds per subscription key -->
<rate-limit calls="100" renewal-period="60" />
<!-- Or by IP address -->
<rate-limit-by-key calls="50" renewal-period="60"
counter-key="@(context.Request.IpAddress)" />
</inbound>
<inbound>
<validate-jwt header-name="Authorization" require-scheme="Bearer"
failed-validation-httpcode="401">
<openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
<required-claims>
<claim name="aud" match="all">
<value>{api-client-id}</value>
</claim>
</required-claims>
</validate-jwt>
</inbound>
<inbound>
<!-- Cache GET responses for 300 seconds -->
<cache-lookup vary-by-developer="false" vary-by-developer-groups="false"
downstream-caching-type="none" />
</inbound>
<outbound>
<cache-store duration="300" />
</outbound>
<inbound>
<!-- Add a header -->
<set-header name="X-Request-Source" exists-action="override">
<value>api-gateway</value>
</set-header>
<!-- Remove a header -->
<set-header name="X-Internal-Token" exists-action="delete" />
<!-- Rewrite URL -->
<rewrite-uri template="/api/v2/orders" />
</inbound>
<inbound>
<cors allow-credentials="true">
<allowed-origins>
<origin>https://myapp.com</origin>
<origin>https://admin.myapp.com</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
<method>PUT</method>
<method>DELETE</method>
</allowed-methods>
<allowed-headers>
<header>Authorization</header>
<header>Content-Type</header>
</allowed-headers>
</cors>
</inbound>
<backend>
<forward-request timeout="30" />
</backend>
<on-error>
<return-response>
<set-status code="503" reason="Service Unavailable" />
<set-body>{"error": "Backend temporarily unavailable"}</set-body>
</return-response>
</on-error>

Policies can be applied at different scopes (inner scopes inherit outer):

Global (all APIs)
└── Product (all APIs in a product)
└── API (all operations in an API)
└── Operation (single endpoint)
MethodUse CaseConfiguration
Subscription keySimple API key in header or queryBuilt-in, per-product
OAuth 2.0 / JWTToken-based auth (Entra ID)validate-jwt policy
Client certificateMutual TLSvalidate-client-certificate policy
Basic authLegacy systemsauthentication-basic policy
Managed identityBackend auth (APIM → backend)authentication-managed-identity policy
Terminal window
# Clients include the key in the header
curl -H "Ocp-Apim-Subscription-Key: abc123..." \
https://myapp-api.azure-api.net/orders

APIM supports multiple versioning schemes:

SchemeExample
URL path/v1/orders, /v2/orders
Query string/orders?api-version=2026-02-01
HeaderApi-Version: v2
Terminal window
# Create a version set
az apim api versionset create \
--resource-group myapp-rg \
--service-name myapp-api \
--display-name "Orders API" \
--versioning-scheme "Segment" \
--version-set-id "orders-versions"
# Create v2 of the API
az apim api create \
--resource-group myapp-rg \
--service-name myapp-api \
--api-id "orders-v2" \
--display-name "Orders API v2" \
--path "orders" \
--api-version "v2" \
--api-version-set-id "orders-versions" \
--service-url "https://myapp-v2.azurewebsites.net"

APIM includes a self-service developer portal where API consumers can:

  • Browse available APIs and operations.
  • View request/response schemas and examples.
  • Test APIs interactively (built-in test console).
  • Sign up for products and get subscription keys.
  • View usage analytics and quotas.

The portal is auto-generated from your API definitions and can be customized with branding.

APIM provides built-in analytics:

MetricWhat It Shows
RequestsTotal calls, success rate, error breakdown (4xx, 5xx)
LatencyGateway processing time + backend response time
CapacityGateway resource utilization
Cache hit ratioPercentage of requests served from cache

Integrate with:

  • Application Insights — Detailed request tracing, dependency maps.
  • Azure Monitor — Alerts on error rates or latency.
  • Event Hubs — Stream API logs for custom analytics.

APIM vs Application Gateway vs Azure Front Door

Section titled “APIM vs Application Gateway vs Azure Front Door”
APIMApplication GatewayAzure Front Door
Primary roleAPI gateway (L7 API management)Load balancer (L7 web traffic)Global CDN + load balancer
PoliciesRate limiting, JWT, caching, transformationWAF, SSL, routingWAF, caching, routing
Developer portalYesNoNo
API versioningYesNoNo
Best forAPI consumers, partners, mobile backendsWeb applications, WAFGlobal web apps, CDN
  • APIM centralizes authentication, rate limiting, caching, and monitoring for your APIs.
  • Policies (XML) are the core mechanism — applied at inbound, backend, outbound, and on-error stages.
  • Products group APIs with shared policies and subscription keys.
  • JWT validation with Entra ID is the recommended auth method for modern APIs.
  • The developer portal gives API consumers self-service documentation and testing.
  • Consumption tier is serverless and cost-effective for low-traffic APIs; Standard/Premium for production.
  • Use APIM for API management; use Application Gateway for web traffic and WAF.