Rate-limit your API's customers
Say your product has its own public API, and each customer calls it with their own API key. You want each key to make at most 60 requests in any minute and 1,000 in any hour, so one customer’s script can’t slow everyone else down.
1. Create two limits
Section titled “1. Create two limits”One over any minute for bursts, and one over any hour, both on the
subject kind apikey:
import { createClient } from "@limitry/sdk";
const limitry = createClient();
await limitry.limits.create({ name: "API burst", subjectKind: "apikey", action: "api-request", amount: 60, window: "minute", rolling: true,});await limitry.limits.create({ name: "API per hour", subjectKind: "apikey", action: "api-request", amount: 1000, window: "hour", rolling: true,});from limitry import Limitry
limitry = Limitry()
limitry.limits.create( name="API burst", subject_kind="apikey", action="api-request", amount=60, window="minute", rolling=True,)limitry.limits.create( name="API per hour", subject_kind="apikey", action="api-request", amount=1000, window="hour", rolling=True,)limitry limits create --name "API burst" --subject-kind apikey \ --action api-request --amount 60 --window minute --rollinglimitry limits create --name "API per hour" --subject-kind apikey \ --action api-request --amount 1000 --window hour --rollingcurl -X POST https://api.limitry.com/v1/limits \ -H "Authorization: Bearer $LIMITRY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"API burst","subjectKind":"apikey","action":"api-request", "amount":60,"window":"minute","rolling":true}'
curl -X POST https://api.limitry.com/v1/limits \ -H "Authorization: Bearer $LIMITRY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"API per hour","subjectKind":"apikey","action":"api-request", "amount":1000,"window":"hour","rolling":true}'Rolling windows count the last 60 seconds or 60 minutes at the moment of each request, so there’s no burst allowed at the top of the hour.
2. Check each request
Section titled “2. Check each request”Check before handling the request, using your customer’s key id as the subject. That’s the key your customer sends to your API, not your Limitry key. Both limits apply, and the request is allowed only if it fits both:
import { createClient, LimitExceeded } from "@limitry/sdk";
const limitry = createClient(); // reads LIMITRY_API_KEY
export async function handle(request: Request, customerKeyId: string) { try { return await limitry.guard( { subject: { kind: "apikey", id: customerKeyId }, action: "api-request" }, () => route(request), ); } catch (err) { if (err instanceof LimitExceeded) { return new Response("Too many requests", { status: 429, headers: { "Retry-After": String(err.retryAfterSeconds ?? 60) }, }); } throw err; }}from flask import Responsefrom limitry import LimitExceeded, Limitry
limitry = Limitry() # reads LIMITRY_API_KEY
def handle(request, customer_key_id: str): try: with limitry.guard( subject={"kind": "apikey", "id": customer_key_id}, action="api-request" ): return route(request) except LimitExceeded as err: return Response( "Too many requests", status=429, headers={"Retry-After": str(err.retry_after_seconds or 60)}, )Both limits keep the default fail mode, open: if Limitry can’t be
reached, requests go through rather than your API going down with it.
3. A bigger allowance for some customers
Section titled “3. A bigger allowance for some customers”A limit for one key (with subjectId set) replaces the kind’s limit
with the same action and window, so it can raise that key’s allowance
or lower it. Use it for one customer you’ve agreed a deal with.
To give everyone on a bigger plan more, use a subject kind per plan,
such as apikey-pro with its own limits, and send that kind for their
keys.
4. See who is hitting it
Section titled “4. See who is hitting it”The Usage page shows, for each limit, the keys using it right now and how many of their requests were turned away.
Related: Rolling windows and concurrency, Checks.