Safe Retries and Rate Limits
Network failures, timeouts, and retries are inevitable in distributed systems. Recurso provides two mechanisms to help you build resilient integrations:- Idempotency — Safely retry requests without causing duplicate side effects (double charges, duplicate subscriptions)
- Rate Limiting — Protect the platform and your account from excessive request volume
Idempotency
How It Works
Every mutating API request (POST, PUT, PATCH, DELETE) can include anIdempotency-Key header. Recurso uses this key to detect duplicate requests and return the original response instead of processing the request again.
Using the Idempotency-Key Header
Include the header on any request that creates or modifies resources:Key Format Recommendations
Idempotency Rules
Keys are scoped to your API key
Keys are scoped to your API key
Two different API keys can use the same idempotency key value without conflict. Keys are scoped to the authenticated API key making the request.
Keys expire after 24 hours
Keys expire after 24 hours
Idempotency keys are stored for 24 hours. After that, the same key can be reused for a new request. This prevents unbounded storage growth while covering typical retry windows.
Request body must match
Request body must match
If you reuse an idempotency key with a different request body, Recurso returns a
422 Unprocessable Entity error. This prevents accidental misuse where different operations share a key.Only mutating requests are idempotent
Only mutating requests are idempotent
GET requests are naturally idempotent and do not require an
Idempotency-Key header. The header is only checked on POST, PUT, PATCH, and DELETE requests.Error responses are not cached
Error responses are not cached
If the original request returned a 4xx or 5xx error, the idempotency key is released. Retrying with the same key will re-execute the request, giving you a chance to succeed after a transient failure.
Idempotency Best Practices
- Always use idempotency keys for payment-related operations — Creating subscriptions, recording payments, and issuing refunds should always include an idempotency key
- Generate keys client-side — Generate the key before sending the request so retries use the same key
- Store keys alongside business operations — Log the idempotency key with your internal transaction ID for traceability
- Do not reuse keys across different operations — Each distinct business operation should have a unique key
Rate Limiting
Recurso enforces rate limits per API key to ensure platform stability and fair usage.Rate Limit Tiers
Rate limits are applied per API key, not per tenant. If you have multiple API keys, each has its own independent rate limit counter.
Rate Limit Headers
Every API response includes headers that tell you your current rate limit status:Handling 429 Too Many Requests
When you exceed the rate limit, Recurso returns a429 Too Many Requests response with a Retry-After header:
Retry Strategies
Exponential Backoff
The recommended retry strategy uses exponential backoff with jitter to avoid thundering-herd problems:Retry Decision Table
Monitoring Rate Limit Usage
Track your rate limit consumption to proactively avoid hitting limits:Best Practices
Always Use Idempotency Keys
Include idempotency keys on every mutating request, especially payments and subscription changes.
Respect Retry-After
When you receive a 429, always honor the
Retry-After header rather than using a fixed delay.Add Jitter to Backoff
Randomize retry delays to prevent multiple clients from retrying in lockstep and overwhelming the API.
Cache Read Results
Cache GET responses locally to reduce API calls. Use webhooks for real-time updates instead of polling.
Use Bulk Endpoints
Prefer batch APIs (e.g.,
usage.recordBatch) over individual calls to stay within rate limits on high-volume operations.Monitor and Alert
Set up monitoring on
X-RateLimit-Remaining. Alert your team when remaining requests drop below 10% of the limit.