Most rate-limit documentation makes integrators build for a wall that will never be hit. Worthune publishes two numbers with two different natures — and the right client architecture follows from knowing which is which.
Every vendor integration eventually has the rate-limit conversation, and it usually happens twice: once when an engineer reads the docs and once when something returns a 429 in production. This piece is the whole conversation in one place: what the two published numbers mean, what the client should actually do about each, and what is safe to cache.
The hard number: 120 per minute, per IP
The only enforced limit is a burst backstop: 120 requests a minute per IP. Exceed it and the API returns HTTP 429 with a retry-after header stating how long to wait. Its purpose is narrow — stopping runaway loops and script accidents, not metering real usage. A user filling in a form, or even a busy product server fanning out requests for a page render, does not approach two requests a second sustained for a minute from one address.
if status == 429: wait retry-after seconds, then retry the same request once; if it recurs, surface it — a loop is running somewhere
The retry-after header is the contract: honor it rather than guessing with exponential backoff from zero. And treat a recurring 429 as a bug report about your own code, because at 120 per minute per IP, sustained hits almost always mean an unintended loop — a useEffect without a dependency array, a retry storm, a load test pointed at production.
One distinction spares a lot of wasted retry logic: 429 is the only response worth retrying automatically. A validation failure is deterministic — the same rejected input will be rejected identically every time, so retrying it is a tight loop that produces nothing but progress toward the backstop. Retry on 429 with the header's delay; on ok: false, fix the input instead.
The soft number: 5,000 runs a month
Fair use is 5,000 model runs a month per application — and the pricing page is explicit about its nature: a guideline, not a meter. Nothing blocks request 5,001. The published commitment is that if enforcement ever becomes necessary, it arrives with notice and generous headroom, not retroactively. An application consistently above the guideline is succeeding, and that is a design-partner conversation, not a shutoff.
The architectural consequence: do not build quota-tracking infrastructure for the fair-use number. Teams that treat 5,000 as a hard ceiling add counters, alerts, and degradation paths for a wall that does not exist. A monthly glance at your own request volume — which you want for capacity planning anyway — is the entire discipline the guideline asks for.
| Number | Nature | Client response |
|---|---|---|
| 120 requests per minute per IP | Enforced backstop with 429 and retry-after | Honor the header and investigate recurrences as bugs |
| 5,000 runs per month per app | Published guideline with a written no-surprises commitment | Watch your volume and start a conversation if you live above it |
What is safe to cache
Caching is the legitimate way to keep a chatty product under any limit, and the envelope's own structure says what is cacheable. A model run is deterministic: the same model, spec version, and inputs produce the same outputs — the whole verification story depends on it. So a cache keyed on model plus specVersion plus the canonical inputs is sound, and the record’s canonical-JSON convention doubles as the key-serialization recipe. Two rules keep it honest:
- Key the cache on model, specVersion, and inputs together — never on inputs alone.
- Invalidate when the spec version moves — your CI drift fixture already detects this.
- Cache contract responses briefly if you fetch them at render time — they change only with releases.
- Never hard-code a constant out of a cached response — constants belong to the facts registry, which carries the period and source the cached copy silently drops.
- Do not cache across users if inputs are user-specific — identical inputs are rarer than they look.
The subtle item is the fourth. A cached envelope contains, say, a contribution limit inside its facts array — accurate for the run it describes. Copying that number out of the cache into your own code turns a cited, dated constant into an undated hard-coded one, and next January it is quietly wrong. The envelope is cacheable as a unit; its constants are not extractable as facts that stand alone.
Interactive surfaces: debounce, do not meter
A slider wired directly to the API generates a request per pixel of drag — the one realistic way a legitimate UI approaches the burst backstop. The fix is standard front-end hygiene, not rate-limit engineering: debounce to one request per settled value, cancel in-flight requests when a newer one supersedes them, and render the last result while the next loads. A debounced slider lands at a handful of requests per user interaction, which is nowhere near any number on this page.
Where usage is public
One more number worth knowing exists: Worthune publishes its own aggregate usage at /api/v1/telemetry — daily hit counts per surface for the last thirty days, with an explicit privacy note that only aggregate counters are stored, never IPs, user agents, or inputs. For an integrator, that endpoint is a transparency artifact: the platform holding your dependency shows its own traffic shape in public, the same show-your-work posture as the specs.
Sources
- [1] Worthune pricing (fair use and backstop, in writing). https://worthune.com/pricing
- [2] Worthune API documentation. https://worthune.com/docs