Rate limits
How 429 works, how to back off with exponential delay and jitter, and why fan-message pacing is a separate, fixed safety mechanism.
The API is rate limited per account to keep the platform fast and fair for everyone. A
well-behaved client almost never notices a limit; a client that loops a single read
thousands of times in a tight loop will. When you exceed a limit, the API responds with
429 Too Many Requests.
How 429 works
A 429 is not an error in your payload — your request was well-formed, you simply asked for
too much, too fast. It carries the standard error shape:
{
"error": "rate_limited",
"message": "Too many requests. Retry after a short backoff."
}The correct response to a 429 is always the same: wait, then retry the same request.
A 429 is transient and safe to retry — unlike a 400, which will fail identically until
you fix the request.
Treat 429 as advisory pressure, not failure. Build retry-with-backoff into your client
once, and rate limits become invisible.
Back off with exponential delay and jitter
Retry on a growing delay, and add jitter — a small random offset — so that many clients (or many retries) don't all wake up and retry at the same instant and re-collide. Exponential growth keeps you from hammering the API; jitter spreads the herd.
async function withRetry(fn: () => Promise<Response>, tries = 5): Promise<Response> {
for (let i = 0; i < tries; i++) {
const res = await fn();
if (res.status !== 429) return res;
// exponential base (250ms, 500ms, 1s, 2s, …) + up to 250ms of jitter
const delay = 2 ** i * 250 + Math.random() * 250;
await new Promise((r) => setTimeout(r, delay));
}
throw new Error('still rate limited after retries');
}import random, time, requests
def with_retry(make_request, tries=5):
for i in range(tries):
res = make_request()
if res.status_code != 429:
return res
# exponential base (0.25s, 0.5s, 1s, 2s, …) + up to 0.25s of jitter
time.sleep(2 ** i * 0.25 + random.random() * 0.25)
raise RuntimeError("still rate limited after retries")Cap the number of retries (the snippets above stop after five) so a sustained limit surfaces as a real error instead of hanging your job forever.
Stay under the limit in the first place
Backoff is the safety net. The cheaper fix is to make fewer, larger requests:
- Batch. Where an endpoint accepts a list or returns a page, ask for many items in one
call instead of looping one request per item. Paginate with a generous
limitrather than fetching one row at a time — see Pagination. - Cache. Reads that change slowly (configuration, link metadata, segment definitions) can be fetched once and reused. Re-fetch on a sensible interval or when you make a write that would change them, not on every iteration of a loop.
- Poll politely. If you watch a value for changes, poll on an interval with backoff, not in a busy loop. Most data does not change second to second.
- Spread bursts. A nightly job that fires thousands of requests in one second will trip the limiter; the same job spread over a few seconds will not.
Most 429s come from a single hot loop. Find the loop that issues one request per row and
replace it with a batched or paginated call, and the limit usually disappears.
Fan-message pacing is a separate, fixed safety mechanism
Do not confuse the API rate limit with how fast your outbound fan messages are delivered. They are unrelated systems with opposite purposes.
| API rate limit | Outbound message pacing | |
|---|---|---|
| Protects | Platform performance and fairness | Your connected account's safety |
| Applies to | Your calls to the TEASE API | Delivery of messages to fans |
| On limit | 429, retry with backoff | N/A — pacing is built into delivery |
| Tunable? | Effectively yes, via backoff and batching | No |
When you build, preview, and schedule a broadcast, the API accepts it quickly. The actual delivery to fans is then released on a deliberately conservative, account-safe cadence that cannot be sped up — there is no priority flag, no "send now," and no parameter that shortens it. This pacing is the point: it is what keeps a connected account in good standing.
Outbound fan messaging has its own, deliberately conservative pacing for account safety. It is not a knob you can turn up, and retrying or re-submitting will not make messages go out faster. See Chat & broadcasts.
Next steps
- Response structure — the
429body and status table. - Chat & broadcasts — how scheduling and safe pacing work.
- Security — how the perimeter and per-account limits are enforced.
- FAQ — quick answers on limits, safety, and keys.
Response structure
JSON conventions, timestamps, the error shape, the full HTTP status table, and pagination — documented once for the whole API.
Credits & usage
What one credit is, which actions cost a credit and which are free, how monthly plan allowances and rollover work, and where to watch your usage in real time.