Rate limits
How much you can ask for, what a 429 looks like, and how to back off.
The limit is per organization, not per key: creating a second key doesn't buy you a second budget. That's deliberate — the budget belongs to the account, and splitting it by credential would mean the load on our side depends on how many keys somebody happened to create.
| Window | Limit |
|---|---|
| Per minute | 120 requests |
| Per hour | 3,000 requests |
Both are evaluated, and whichever runs out first is the one that stops you. There's also a wide per-IP backstop, high enough that it only catches a single machine flooding us — a partner integrating many organizations from one server won't meet it.
What a 429 looks like
HTTP/1.1 429 Too Many Requests
Retry-After: 24
RateLimit: "minute";r=0;t=24
RateLimit-Policy: "minute";q=120;w=60, "hour";q=3000;w=3600{ "error": { "code": "API_KEY_RATE_LIMITED", "message": "Rate limit exceeded for this API key." } }Retry-After is in seconds and it's the real number — waiting that long is enough. Read it instead of guessing a backoff: a fixed sleep is either slower than it needs to be or not long enough.
Successful responses (and the 429) also send IETF RateLimit / RateLimit-Policy headers: remaining quota and the organization windows (120/min and 3,000/hour). Read RateLimit to slow down before you hit the ceiling; Retry-After is still the number to wait on a 429.
async function call(url, init) {
for (let attempt = 0; attempt < 5; attempt++) {
const res = await fetch(url, init);
if (res.status !== 429) return res;
const wait = Number(res.headers.get("Retry-After") ?? 5);
await new Promise((r) => setTimeout(r, wait * 1000));
}
throw new Error("Still rate limited after 5 attempts");
}Staying under it
- Ask for bigger pages.
limit=100reads four times as much per request as the default 25 — see Pagination. - Poll on a schedule, not in a loop. There are no webhooks yet, so polling is the pattern; the mistake is polling as fast as the code can run rather than as fast as the data changes.
- Handle the 429 rather than avoiding it. A retry that reads
Retry-Afteris more robust than a rate you tuned once and never revisited.
If your integration genuinely needs more than this, write to support@trama.so and tell us the shape of the traffic. These numbers are a starting ceiling calibrated on real usage, not a commercial limit — there's nothing to buy.