Rate limits
Every Forge Pro API key has two independent per-minute counters, both backed by Redis on the FileForge hub. The defaults are tunable by the operator in admin_settings; the values shown here are the shipping defaults.
| Bucket | Default | What counts |
|---|---|---|
| Request rate | 60/min | Every successful authenticated call. |
| Conversion rate | 5/min | POST /v1/conversions and each item in POST /v1/conversions/bulk. |
| Daily conversions | tier-defined (null = unlimited for Pro/Enterprise) | Every conversion created. |
Daily conversions still respect the tier on your profile — Pro and Enterprise default to unlimited, free is 5/day (and free can't use the public API anyway).
Headers
When you hit the request-rate cap, the response is 429 with:
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1762534812Retry-After is in seconds; X-RateLimit-Reset is a Unix timestamp. Successful calls don't carry the rate-limit headers — we only emit them on rejection to keep the hot path lean.
Backoff strategy
The simplest correct retry is to honour Retry-After:
import time, requests
def call(url, headers):
while True:
r = requests.get(url, headers=headers)
if r.status_code == 429:
time.sleep(int(r.headers.get('Retry-After', 5)))
continue
return rFor long-running batches, slow your fan-out down to ≤ 5 conversions per minute per key — that's the per-conversion budget. Going wider per key just means most of your POSTs 429.
Bursts and bulk
POST /v1/conversions/bulk consumes one conversion-rate token per item, so a 20-item bulk submitted from a fresh window will be accepted but the next 4 minutes' worth of bulk + single calls will get rejected. If you regularly submit large batches, mint a second key and split traffic across them.
Concurrent jobs vs. queue priority
Pro keys submit into the same priority lane the web UI's Pro users use (BullMQ priority 1 vs. free's 5). The API doesn't add a separate fast lane — all your conversions race for whichever Pro slot is available next.
