Reference
Rate limits
Requests made with an API key share one budget per account. Every such response tells you what is left, so you can slow down before you are refused.
Headers
Every response to an API-key request carries these, a 429 included. Requests from the dashboard's browser session are not counted against this budget and send no such headers.
| Header | Meaning |
|---|---|
| X-RateLimit-Limit | Requests allowed per window for the account. |
| X-RateLimit-Remaining | Requests left in the current window. 0 on a 429. |
| X-RateLimit-Reset | Unix time in seconds when the window resets. |
| Retry-After | Whole seconds to wait before retrying. Sent with a 429 only. |
Read the limit, do not hard-code it
The limit is currently 600 requests per minute. It is reported on every response and is not part of the versioned contract, so size your client from
X-RateLimit-Limit.curl
curl -sS -i "$RAVELO_API/v1/payment-intents?limit=1" \
-H "Authorization: Bearer $RAVELO_TEST_KEY"TypeScript
import { Ravelo, RaveloError } from "@ravelo/sdk";
const ravelo = new Ravelo({ apiKey: process.env.RAVELO_TEST_KEY!, baseUrl: process.env.RAVELO_API! });
try {
await ravelo.paymentIntents.list({ limit: 1 });
// The budget reported by the latest response.
const budget = ravelo.rateLimit;
if (budget) console.log(`${budget.remaining} of ${budget.limit} left, resets ${budget.resetAt.toISOString()}`);
} catch (err) {
// The SDK already retried twice, waiting for Retry-After each time.
if (err instanceof RaveloError && err.code === "rate_limited") console.log("retry in", err.rateLimit?.retryAfter, "seconds");
else throw err;
}Python
import os
from ravelo import Ravelo, RaveloError
ravelo = Ravelo(os.environ["RAVELO_TEST_KEY"], os.environ["RAVELO_API"])
try:
ravelo.payment_intents.list(limit=1)
# The budget reported by the latest response.
budget = ravelo.rate_limit
if budget:
print(f"{budget.remaining} of {budget.limit} left, resets at {budget.reset}")
except RaveloError as err:
# The SDK already retried twice, waiting for Retry-After each time.
if err.code != "rate_limited":
raise
print("retry in", err.rate_limit.retry_after if err.rate_limit else None, "seconds")When you are over
The API answers 429 with the error code rate_limited and retryable: true. The TypeScript and Python SDKs wait for Retry-After (at most 30 seconds) and retry twice before they raise. If you call the API directly, do the same.
- Wait at least
Retry-Afterseconds, then retry with the sameIdempotency-Key. - Add jitter when several workers share a key, so they do not retry in step.
- Do not poll payments in a tight loop. Use webhooks, or read the
/v1/eventsstream by cursor, which returns only what is new. - Spread batch jobs, such as a nightly reconciliation, over time instead of bursting.