API ReferenceErrors & Rate Limits
Errors & Rate Limits
HTTP status codes, error response format, rate limiting details, and retry strategies for the ReelPlus API.
Error Response Format
All API errors return a consistent JSON structure:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "A human-readable description of what went wrong."
}
}HTTP Status Codes
| Status | Meaning | When It Occurs |
|---|---|---|
200 | OK | Request succeeded |
304 | Not Modified | Content unchanged (cached) |
400 | Bad Request | Invalid parameters or malformed request |
401 | Unauthorized | Missing or invalid Authorization header |
403 | Forbidden | Invalid/revoked API key or plan does not include API access |
404 | Not Found | Resource does not exist |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Unexpected server error |
Error Codes
400 — Bad Request
| Code | Message | Fix |
|---|---|---|
INVALID_DATE | Invalid date format | Use ISO 8601: YYYY-MM-DD |
INVALID_DATE_RANGE | start_date after end_date | Swap your dates |
INVALID_PARAMETER | Invalid value | Check endpoint docs |
MISSING_PARAMETER | Required param missing | Include required params |
401 — Unauthorized
| Code | Message | Fix |
|---|---|---|
UNAUTHORIZED | Missing or invalid Authorization header | Add Authorization: Bearer rp_xxx |
403 — Forbidden
| Code | Message | Fix |
|---|---|---|
INVALID_API_KEY | Key not found or revoked | Generate a new key from Settings > API Access |
PLAN_LIMIT | API requires Starter+ plan | Upgrade from Settings > Plans |
429 — Rate Limited
| Code | Message | Fix |
|---|---|---|
RATE_LIMIT_EXCEEDED | Too many requests | Wait and retry (see below) |
Rate Limiting
Limits
| Scope | Limit | Window |
|---|---|---|
| Per API Key | 60 requests | 1 minute (rolling) |
Response Headers
Every response includes:
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit | Max requests per window | 60 |
X-RateLimit-Remaining | Remaining in current window | 45 |
X-RateLimit-Reset | Unix timestamp of reset | 1706540400 |
When exceeded, you also get Retry-After (seconds to wait).
Retry Strategy
Implement exponential backoff for production integrations:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.ok) return response.json();
if (response.status === 429) {
const retryAfter = response.headers.get("Retry-After");
const wait = retryAfter
? parseInt(retryAfter, 10) * 1000
: Math.pow(2, attempt) * 1000;
await new Promise(r => setTimeout(r, wait));
continue;
}
if (response.status >= 500) {
await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
continue;
}
const error = await response.json();
throw new Error(`${response.status}: ${error.error.message}`);
}
throw new Error("Max retries exceeded");
}import time, requests
def fetch_with_retry(url, headers, params=None, max_retries=3):
for attempt in range(max_retries):
resp = requests.get(url, headers=headers, params=params)
if resp.ok:
return resp.json()
if resp.status_code == 429:
wait = int(resp.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
continue
if resp.status_code >= 500:
time.sleep(2 ** attempt)
continue
raise Exception(f"{resp.status_code}: {resp.json()['error']['message']}")
raise Exception("Max retries exceeded")Never retry 401 or 403 errors — they require manual intervention (new key or plan upgrade). Only retry 429 and 5xx errors.