OyeFilmy Logo
personFreeUpgrade
bolt0cr
U

Get started

Rate Limits

OyeFilmy uses per-key rate limiting to ensure fair usage and protect the platform.

How rate limiting works

Two limits apply independently, and whichever you hit first returns 429:

LimitValueScope
Per API key120 req/min by default — set it to anything from 10 to 6000 when you create the keyThat key alone, across all endpoints
Platform-wide300 req/minPer client, applied to every request including unauthenticated ones

Rate limits are a property of the key, not of your subscription plan — a Free Trial key and an Enterprise key with the same configured RPM behave identically. Choose the limit when you create the key on the API Keys page.

Rate limit headers

Responses carry the platform-wide limit, not your key's limit:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 294
X-RateLimit-Reset: 27
HeaderDescription
X-RateLimit-LimitThe platform-wide ceiling (300/min). This is not your key's configured RPM.
X-RateLimit-RemainingRequests left in the current platform-wide window
X-RateLimit-ResetSeconds until the window resets — a countdown, not a Unix timestamp

These headers are not exposed to browser JavaScript: the API does not send Access-Control-Expose-Headers, so fetch() in a browser reads them as null. They are readable from any server-side client. Never call the API directly from a browser with a live key anyway — see Authentication.

HTTP 429 response

Exceeding your key's own limit returns:

HTTP 429 Too Many Requests
{
  "statusCode": 429,
  "timestamp": "2026-08-08T11:06:39.135Z",
  "path": "/api/generate/reframe/history",
  "requestId": "a0a31e77-dc8a-4184-b347-802ffdcfc2fc",
  "message": "Rate limit exceeded for this API key (10/min)."
}

There is no Retry-After header and no retryAfter field. The window is a rolling 60 seconds, so retry after a delay of your own choosing — see below. Include the requestId if you contact support about a request.

Best practices

Exponential backoff: on a 429, back off and retry with growing delays (1s, 2s, 4s…) plus a little jitter. Because the window is a rolling 60 seconds, a retry within the same minute can still be rejected.

// The API sends no Retry-After header, so back off on your own schedule.
async function callWithRetry(fn, maxRetries = 4) {
  for (let i = 0; i < maxRetries; i++) {
    const res = await fn();
    if (res.status !== 429) return res;

    // Exponential backoff + jitter, so parallel workers don't retry in lockstep.
    const waitMs = Math.pow(2, i) * 1000 + Math.random() * 500;
    console.log(`Rate limited. Retrying in ${Math.round(waitMs)}ms...`);
    await new Promise(r => setTimeout(r, waitMs));
  }
  throw new Error("Max retries exceeded");
}

Tips for staying within limits

  • Batch requests: Group multiple prompts and send them sequentially rather than all at once.
  • Use webhooks: Replace polling with webhooks to eliminate status-check requests.
  • Cache results: Cache completed generation results to avoid re-generating identical prompts.
  • Size the key to the job: your key's RPM is set at creation and can go up to 6000 — give a production integration its own key with a limit that matches its traffic.
  • Watch the platform headers server-side: X-RateLimit-Remaining tracks the 300/min platform ceiling, not your key's limit, and is unreadable from browser JavaScript.