ReelPlusReelPlus Help

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

StatusMeaningWhen It Occurs
200OKRequest succeeded
304Not ModifiedContent unchanged (cached)
400Bad RequestInvalid parameters or malformed request
401UnauthorizedMissing or invalid Authorization header
403ForbiddenInvalid/revoked API key or plan does not include API access
404Not FoundResource does not exist
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error Codes

400 — Bad Request

CodeMessageFix
INVALID_DATEInvalid date formatUse ISO 8601: YYYY-MM-DD
INVALID_DATE_RANGEstart_date after end_dateSwap your dates
INVALID_PARAMETERInvalid valueCheck endpoint docs
MISSING_PARAMETERRequired param missingInclude required params

401 — Unauthorized

CodeMessageFix
UNAUTHORIZEDMissing or invalid Authorization headerAdd Authorization: Bearer rp_xxx

403 — Forbidden

CodeMessageFix
INVALID_API_KEYKey not found or revokedGenerate a new key from Settings > API Access
PLAN_LIMITAPI requires Starter+ planUpgrade from Settings > Plans

429 — Rate Limited

CodeMessageFix
RATE_LIMIT_EXCEEDEDToo many requestsWait and retry (see below)

Rate Limiting

Limits

ScopeLimitWindow
Per API Key60 requests1 minute (rolling)

Response Headers

Every response includes:

HeaderDescriptionExample
X-RateLimit-LimitMax requests per window60
X-RateLimit-RemainingRemaining in current window45
X-RateLimit-ResetUnix timestamp of reset1706540400

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.