Core concepts

Rate limits

Three limits protect the service: requests per minute per key, jobs running at once per account, and a daily upload allowance per account.

Limits by plan

LimitFreeCreatorInfluencerAgency
Sustained generations per minute, per account~1~2~5~10
Requests per minute, per key3060120240
API jobs running at once, per account241020
Active API keys12520
Webhook endpoints12520
Social accounts includedNot on Free2515
Characters / products1 / 13 / 510 / 2030 / 50

Request rate

Each key has a token bucket that refills continuously at its per-minute rate, so short bursts are fine. Every response carries X-RateLimit-Limit. Over the limit you receive 429 RATE_LIMITED with a Retry-After header in seconds.

Concurrent jobs

A job is a generation that is queued or processing. When the account already has its maximum running, new image and video requests return 429 CONCURRENCY_LIMIT (Retry-After: 15) without charging. The slot frees as soon as a generation finishes, fails or is cancelled.

See your live numbers at GET /account (limits.concurrent_jobs and usage_now.active_jobs) or in Dashboard → Developers.

For batches, keep a local queue and submit a new request whenever one finishes (use webhooks), rather than submitting everything at once. Keep in flight at most limits.concurrent_jobs − usage_now.active_jobs.

Uploads per day

Uploads cost no credits, so each account has a daily allowance of new files and bytes. Every file Orior stores for you counts: POST /uploads in any mode, and https or data URLs in media fields, which are stored as uploads too. Reusing an upload ID or an Orior URL does not count.

Per account, per UTC dayFreeCreatorInfluencerAgency
New files503001,0005,000
Bytes1 GB10 GB50 GB250 GB

A file counts when its upload starts: a signed upload when upload_url is issued, a URL import before the download, so failed uploads count too. Its bytes count when they are known: right away for URL and data imports, and when a signed upload turns ready. A signed upload that would go over at that point is deleted.

Over the allowance you receive 429 RATE_LIMITED with Retry-After set to the seconds until 00:00 UTC, when the count starts again. Reuse upload IDs instead of uploading the same file twice.

Throughput

Throughput per account is set by the job limit and how long generations take:

TypicalAt busy times
Image, prompt only~60–90 sup to ~4 min
Image with character + scene~1.5–2 minup to ~5 min
Video1–6 minlonger for 12–15 s clips

So an account with N parallel jobs sustains roughly N ÷ 2 images per minute — about 5/min on Influencer and 10/min on Agency. Capacity is shared with other customers; limits are sized so everyone keeps these rates.

Need more? Email support@oriorai.com with your expected volume — higher limits are set per account, and GET /account reflects them immediately.

Handling 429s

Node.js — retry with backoff
async function withRetry(send, attempts = 5) {
  for (let attempt = 0; ; attempt++) {
    const res = await send()
    if (res.status !== 429 || attempt === attempts - 1) return res
    const wait = Number(res.headers.get('retry-after')) || 2 ** attempt
    await new Promise(resolve => setTimeout(resolve, wait * 1000))
  }
}

// Reuse the same Idempotency-Key across retries of one logical request.
const key = crypto.randomUUID()
const res = await withRetry(() => fetch(url, { method: 'POST', headers: { ...auth, 'Idempotency-Key': key }, body }))

Rate-limited responses are never stored against the Idempotency-Key, so retrying with the same key is safe.