Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.arcmira.com/llms.txt

Use this file to discover all available pages before exploring further.

Every Arcmira API key is rate limited per minute. Limits are tier-based but can be overridden on individual keys for enterprise use cases.

Default limits

Plan tierRequests per minute
Free60
Paid (Pro, Pro+)240
Teams / Enterprise600
Each tier represents what a single API key is allowed. If you have multiple keys, each one has its own bucket. If your plan needs a different ceiling, contact us at hi@arcmira.com — per-key overrides are common for high-throughput integrations.

Response headers

Every response (including errors) carries the current bucket state:
HeaderDescription
RateLimit-LimitRequests allowed per minute for this key.
RateLimit-RemainingRequests left in the current 60-second window.
RateLimit-ResetUnix epoch (seconds) when the current window resets.
When you exceed the limit, you also get:
HeaderDescription
Retry-AfterSeconds to wait before the next attempt. Always honor it.

Error shape on throttle

{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Try again after 1747200120.",
    "doc_url": "https://docs.arcmira.com/errors#rate_limit_exceeded",
    "request_id": "req_..."
  }
}
HTTP status is 429.

Practical backoff

Node 20+
async function callWithBackoff(url, init, maxRetries = 5) {
  let attempt = 0;
  while (true) {
    const res = await fetch(url, init);
    if (res.status !== 429) return res;
    const retry = Number(res.headers.get('Retry-After') || '1');
    if (attempt++ >= maxRetries) return res;
    await new Promise((r) => setTimeout(r, retry * 1000));
  }
}
Python 3.10+
import asyncio, httpx

async def call_with_backoff(client, method, url, max_retries=5, **kw):
    for attempt in range(max_retries + 1):
        r = await client.request(method, url, **kw)
        if r.status_code != 429:
            return r
        if attempt == max_retries:
            return r
        await asyncio.sleep(int(r.headers.get('retry-after', '1')))

Capacity-side errors

Throttling is different from monthly quota exhaustion. If your included rows are gone and on-demand usage is off, you’ll see 402 quota_exceeded instead of 429. See Usage & billing.