TEASEDocs
Essentials

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 limit rather 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 limitOutbound message pacing
ProtectsPlatform performance and fairnessYour connected account's safety
Applies toYour calls to the TEASE APIDelivery of messages to fans
On limit429, retry with backoffN/A — pacing is built into delivery
Tunable?Effectively yes, via backoff and batchingNo

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 429 body 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.

On this page