1. Examples
  2. Custom Rate Limiting

Custom Rate Limiting

Customize the error response users see when they hit your API rate limits.

Deploy to Zuplo
Deploy to Zuplo

Prerequisite: You need a Zuplo account to run this example. Sign up for free

This example demonstrates how to invoke the Rate Limit policy programmatically and customize the 429 (Too Many Requests) response body with additional context information like rate limit details.

By default, Zuplo's rate limit policy returns a standard 429 response. This example shows how to intercept that response and add useful information like the rate limit configuration, remaining requests, and retry timing.

Prerequisites

  • A Zuplo account. You can sign up for free.

Working with this Example

Locally

Working locally is the best way to explore and understand the code for this example. You can get a local version by using the Zuplo CLI:

Terminalbash
npx create-zuplo-api@latest --example custom-429-response

Then, in the project directory run the following commands:

Terminalbash
npm install
npm run dev

Deploy this example to Zuplo

It is also possible to deploy this example directly to your Zuplo account and work with it via the Zuplo Portal. You can do this by clicking the Deploy to Zuplo button anywhere on this page.

How It Works

This example uses two key techniques:

1. Programmatic Policy Invocation

Instead of applying the rate limit policy directly in the route configuration, a custom policy invokes it programmatically using context.invokeInboundPolicy():

TypeScripttypescript
const result = await context.invokeInboundPolicy("rate-limit-inbound", request);

This allows the custom policy to intercept the response and modify it.

2. Custom 429 Response

When the rate limit is exceeded, the custom policy creates a detailed error response using HttpProblems.tooManyRequests():

TypeScripttypescript
if (result.status === 429) {
  const rateLimits = ContextData.get(context, "rateLimits");
  return HttpProblems.tooManyRequests(request, context, {
    rateLimits,
  });
}

3. ContextData for Passing Information

The rate limit key function stores the rate limit configuration in ContextData, making it available for the custom response:

TypeScripttypescript
ContextData.set(context, "rateLimits", rateLimits);

Project Structure

text
├── config/
│   ├── policies.json      # Policy configurations
│   └── routes.oas.json    # Route definitions
└── modules/
    └── rate-limiting.ts   # Custom rate limit wrapper and key function

Configuration

Rate Limit Settings

The rate limit is configured in config/policies.json:

OptionValueDescription
requestsAllowed2Maximum requests allowed
timeWindowMinutes1Time window for the limit
rateLimitBy"function"Use custom function for rate limit key

Custom Rate Limit Key

The rateLimitKey function in modules/rate-limiting.ts determines how requests are grouped for rate limiting:

TypeScripttypescript
export function rateLimitKey(request, context, policyName) {
  return {
    key: "my-key", // Change to request.user.sub for per-user limits
    requestsAllowed: 2,
    timeWindowMinutes: 1,
  };
}

Testing the Example

Make multiple requests to trigger the rate limit:

Terminalbash
# First two requests succeed (within the 2 request limit)
curl http://localhost:9000/test
curl http://localhost:9000/test

# Third request returns custom 429 response
curl http://localhost:9000/test -i

Expected 429 Response

When rate limited, you'll receive a detailed JSON response:

JSONjson
{
  "type": "https://httpproblems.com/http-status/429",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded",
  "instance": "/test",
  "rateLimits": {
    "key": "my-key",
    "requestsAllowed": 2,
    "timeWindowMinutes": 1
  }
}

Common Customizations

  • Per-user rate limits: Change the key to request.user.sub after adding authentication
  • Different limits per tier: Use request.user.data.tier to set different limits for different customer tiers
  • Add retry-after info: Include timing information in the custom response
  • Log rate limit events: Add logging when rate limits are hit

Key Concepts Demonstrated

  • context.invokeInboundPolicy() - Programmatically invoke other policies
  • ContextData - Pass data between policy functions
  • HttpProblems - Create RFC 7807 compliant error responses
  • CustomRateLimitDetails - Type-safe rate limit configuration

Learn More

  • Rate Limit Policy
  • Custom Policies
  • HTTP Problems
  • Context Data

Quick Links

View on GitHubDocumentation

Run Locally

Clone and run this example:

npx create-zuplo-api --example custom-429-response

On This Page

Related Examples

Explore more examples in this category

Starter

Basic API Gateway

Authentication

Protect your backend API with authentication, rate limiting, and request validation.

View Example

Idempotency Keys

Programmability

Prevent duplicate API requests and ensure safe retries for payments and critical operations.

View Example

Custom Modules

Programmability

Use npm packages and third-party libraries in your Zuplo handlers and policies.

View Example

Dynamic Rate Limits

Programmability

Set different rate limits based on user subscription tier or API key metadata.

View Example
Check all of our Examples

Scale your APIs with
confidence.

Start for free or book a demo with our team.
Book a demoStart for Free
SOC 2 TYPE 2High Performer Spring 2025Momentum Leader Spring 2025Best Estimated ROI Spring 2025Easiest To Use Spring 2025Fastest Implementation Spring 2025

Get Updates From Zuplo

Zuplo logo
© 2026 zuplo. All rights reserved.
Products & Features
API ManagementAI GatewayMCP ServersMCP GatewayDeveloper PortalRate LimitingOpenAPI NativeGitOpsProgrammableAPI Key ManagementMulti-cloudAPI GovernanceMonetizationSelf-Serve DevX
Developers
DocumentationBlogLearning CenterCommunityChangelogIntegrations
Product
PricingSupportSign InCustomer Stories
Company
About UsMedia KitCareersStatusTrust & Compliance
Privacy PolicySecurity PoliciesTerms of ServiceTrust & Compliance
Docs
Pricing
Sign Up
Login
ContactBook a demoFAQ
Zuplo logo
DocsPricingSign Up
Login