API Rate Limits and Retry Strategy¶
Authentication¶
All requests to the API must include a valid Bearer Token in the
Authorization
header (recommended) or in the bearer_token
GET
parameter:
Authorization: Bearer <your_access_token>
OR
https://www.readycloud.com/api/v2/orgs/?bearer_token=<your_access_token>
Rate Limits¶
Every bearer token is associated to an API client, which is subject to rate limiting. Our production API enforces strict throttling rules to ensure fair usage and stability:
- GET requests: up to 30 requests per minute;
- POST / PATCH / DELETE requests: up to 30 requests per minute.
If these limits are exceeded, the server will respond with:
HTTP 429 Too Many Requests
Handling Throttling¶
When a 429 Too Many Requests
response is received, you must back off
before retrying. We recommend using an Exponential Backoff strategy.
Exponential Backoff Algorithm
On the first failure, wait for a short period (e.g., 1 second). On each
subsequent failure, double the wait time, until a max time is reached
and then repeated (e.g. 128s):
1, 2, 4, 8, 16, 32, 64, 128, 128, 128, ...
. Optionally, add a small
random “jitter” to avoid collisions between multiple clients retrying at
the same time.
Request → Success → Done
↓
429 Too Many Requests
↓
Wait 1s → Retry
↓
429 Too Many Requests
↓
Wait 2s → Retry
↓
429 Too Many Requests
↓
Wait 4s → Retry
↓
... (continues with 8s, 16s, etc.)
Python Example¶
Here’s a simple Python implementation of exponential backoff with
requests
:
import time
import random
import requests
import itertools
API_URL = "https://www.readycloud.com/api/v2/orgs/"
TOKEN = "<your_access_token>"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json"
}
def make_request_with_backoff(max_retries=5, base_delay=1):
delay = base_delay
for attempt in itertools.count(1):
if max_retries and attempt > max_retries:
break
response = requests.get(API_URL, headers=headers)
if response.status_code == 200:
return response.json()
if response.status_code == 429:
print(f"Rate limit hit. Retrying in {delay:.1f}s...")
time.sleep(delay + random.uniform(0, 0.5)) # adding random jitter
delay *= 2
else:
response.raise_for_status()
raise Exception("Max retries reached due to throttling.")
# Example usage:
data = make_request_with_backoff()
print(data)
Best Practices¶
- Implement exponential backoff with jitter for all API clients.
- Monitor
429 Too Many Requests
responses in your logs. - If possible, spread requests evenly instead of sending them in bursts.