Rate limits

Aleta meters API traffic per workspace to keep the platform responsive for every integrator. Limits are generous enough that normal backfills, daily syncs, and interactive usage never brush against them — but they do kick in for runaway loops, so every production integration should handle 429 responses gracefully.

Default limits

TierRead requests / minWrite requests / min
Sandbox12030
Production1,200300
EnterpriseCustomCustom

Burst traffic up to double the per-minute budget is absorbed for short windows — a sync that fires 500 requests in 10 seconds won't trip the limiter as long as the trailing minute averages out.

Need higher limits? Reach out on support@aleta.io with a description of your integration's access pattern. Enterprise customers get custom tiers and region-specific pools.

Headers on every response

Every API response carries your current budget — check them instead of guessing. No polling, no extra requests.

  • Name
    X-RateLimit-Limit
    Type
    integer
    Description

    Requests permitted per minute for the current bucket (read or write).

  • Name
    X-RateLimit-Remaining
    Type
    integer
    Description

    Requests left before the limiter engages.

  • Name
    X-RateLimit-Reset
    Type
    integer
    Description

    Unix timestamp (seconds) when the current bucket refills.

  • Name
    Retry-After
    Type
    integer
    Description

    Only present on 429 responses. Seconds to wait before retrying.

Handling 429 Too Many Requests

When you exceed the budget, Aleta responds with 429, a Retry-After header, and no mutation is applied. The canonical response shape applies:

429 Too Many Requests

{
  "error": {
    "type": "rate_limited",
    "code": "too_many_requests",
    "message": "You've hit the per-minute write budget. Retry after 24 seconds.",
    "request_id": "req_01J…"
  }
}

Your integration should honour Retry-After exactly.

Hammering the API during a cooldown window doesn't speed anything up — it extends the window. Repeat offenders have their effective limit temporarily tightened until traffic patterns settle.

Backoff with a jitter

For background workers (batch jobs, resyncs, analytics pipelines), exponential backoff with jitter is the right shape. Raw exponential backoff without jitter causes the "thundering herd" — every worker retries at the same moment and the limiter re-engages immediately.

Backoff with full jitter

async function retryWithBackoff<T>(fn: () => Promise<Response>): Promise<T> {
  let base = 1_000;

  for (let attempt = 0; attempt < 6; attempt++) {
    const res = await fn();

    if (res.status !== 429) {
      if (res.ok) return (await res.json()) as T;
      throw new Error(`API error: ${res.status}`);
    }

    // Prefer Retry-After when the server suggests a value, otherwise
    // fall back to exponential backoff with full jitter.
    const retryAfter = Number(res.headers.get("Retry-After")) * 1_000;
    const capped = Math.min(base * 2 ** attempt, 30_000);
    const delay = retryAfter || Math.random() * capped;

    await new Promise((r) => setTimeout(r, delay));
  }

  throw new Error("Retry budget exhausted");
}

The Aleta SDKs implement this pattern automatically. You only need to roll your own if you're calling the API from raw HTTP.

Cap your backoff at 30 seconds and your retry count at 6 attempts. Anything longer is usually better served by a persistent job queue with scheduled re-runs than by a long-lived retry loop tying up a request handler.

Observability tips

  • Expose X-RateLimit-Remaining as a gauge in your own metrics. When it trends below 20% of the limit during normal operation, you're close to outgrowing your tier and should plan either higher limits or better batching.
  • Tag request spans with the bucket name so a single expensive endpoint can't eat a shared budget invisibly.
  • Use idempotency keys on every mutating request — retries under backoff need them to be safe.

What's next

  • Read about idempotency — always paired with retries in production.
  • Browse the errors reference for the full catalogue of response codes.