Skip to content

Rate limits

The hosted API enforces two independent limits:

Limit Scope Value
Requests per minute per API key 60
Concurrent requests per organization 2

When a limit is exceeded the API returns 429 and no engine work runs.

Headers

Successful responses (200) on metered endpoints include:

Header Meaning
X-RateLimit-Limit-Requests Request limit per minute for this key.
X-RateLimit-Remaining-Requests Requests left in the current window.
X-RateLimit-Reset-Requests Seconds until the window resets.

A 429 also carries Retry-After (seconds to wait before retrying).

429 responses

code Limit Notes
rate_limit_exceeded 60 requests/minute per key Retry-After is set.
concurrency_limit_exceeded 2 concurrent requests per org Retry-After: 1; a slot frees when an in-flight request finishes.
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Melebihi batas 60 request per menit untuk API key ini.",
    "param": null,
    "request_id": "req_01J…",
    "doc_url": "https://docs.trusttyped.com/errors#rate_limit_exceeded"
  }
}

Retrying with backoff

Always honour Retry-After when it is present; otherwise use exponential backoff with jitter. Do not retry immediately in a tight loop.

import httpx, random, time

def post_with_retry(url, *, headers, json, attempts=5):
    delay = 1.0
    for i in range(attempts):
        resp = httpx.post(url, headers=headers, json=json, timeout=120)
        if resp.status_code != 429:
            return resp
        retry_after = resp.headers.get("Retry-After")
        wait = float(retry_after) if retry_after else delay
        time.sleep(wait + random.uniform(0, 0.5))
        delay = min(delay * 2, 30)
    return resp
async function postWithRetry(url, options, attempts = 5) {
  let delay = 1000;
  for (let i = 0; i < attempts; i++) {
    const resp = await fetch(url, options);
    if (resp.status !== 429) return resp;
    const ra = Number(resp.headers.get("Retry-After"));
    const wait = Number.isFinite(ra) ? ra * 1000 : delay;
    await new Promise((r) => setTimeout(r, wait + Math.random() * 500));
    delay = Math.min(delay * 2, 30000);
  }
  throw new Error("rate limited");
}

Concurrency limit = 2 per org

A single organization shares two concurrent engine slots across all its keys. If you need more throughput, spread work over time or contact us about higher limits. Streaming requests also hold a concurrent slot until the stream finishes.