{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-docs/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Rate limits","projectTitle":"Frontline Documentation","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"rate-limits","__idx":0},"children":["Rate limits"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Frontline Public API rate-limits requests ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["per account"]}," to protect platform stability and ensure fair use across customers."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"current-quota","__idx":1},"children":["Current quota"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Scope"},"children":["Scope"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Limit"},"children":["Limit"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Window"},"children":["Window"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Per account"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["1,000 requests"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["60 seconds"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The window is a fixed 60-second bucket that resets on the first request of each window. Requests issued by ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["any"]}," key under the same account count toward the same bucket."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Unauthenticated requests (no valid API key) are rate-limited per IP at the same threshold."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"response-headers","__idx":2},"children":["Response headers"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every successful response includes:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Header"},"children":["Header"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-RateLimit-Limit"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Total requests allowed per window. Currently ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1000"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-RateLimit-Remaining"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Requests remaining in the current window. Drops to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}," at limit."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use these to back off proactively instead of waiting for a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["429"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-you-hit-the-limit","__idx":3},"children":["When you hit the limit"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A request beyond the limit returns:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"http","header":{"controls":{"copy":{}}},"source":"HTTP/1.1 429 Too Many Requests\nContent-Type: application/json\n","lang":"http"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"ok\": false,\n    \"error\": {\n        \"code\": \"internal_error\",\n        \"message\": \"Rate limit exceeded. Please try again later.\"\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wait until the next 60-second window and retry."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"handling-429-in-client-code","__idx":4},"children":["Handling 429 in client code"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A minimal retry loop with exponential backoff:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","header":{"controls":{"copy":{}}},"source":"async function callWithRetry(url, init, attempt = 0) {\n    const res = await fetch(url, init);\n    if (res.status !== 429 || attempt >= 5) return res;\n\n    const delayMs = 1000 * 2 ** attempt; // 1s, 2s, 4s, 8s, 16s\n    await new Promise((r) => setTimeout(r, delayMs));\n    return callWithRetry(url, init, attempt + 1);\n}\n","lang":"js"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import time, requests\n\ndef call_with_retry(url, headers, attempt=0):\n    res = requests.get(url, headers=headers)\n    if res.status_code != 429 or attempt >= 5:\n        return res\n    time.sleep(2 ** attempt)\n    return call_with_retry(url, headers, attempt + 1)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"best-practices","__idx":5},"children":["Best practices"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cache reference data (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/ai-models"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/billing"]},") instead of polling."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Batch listing calls with the highest ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pageSize"]}," you can tolerate (default ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["20"]},", raise it within reason)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run scheduled syncs off-peak."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If you need a higher limit for a legitimate integration, reach out to support."]}]}]},"headings":[{"value":"Rate limits","id":"rate-limits","depth":1},{"value":"Current quota","id":"current-quota","depth":2},{"value":"Response headers","id":"response-headers","depth":2},{"value":"When you hit the limit","id":"when-you-hit-the-limit","depth":2},{"value":"Handling 429 in client code","id":"handling-429-in-client-code","depth":2},{"value":"Best practices","id":"best-practices","depth":2}],"frontmatter":{"seo":{"title":"Rate limits"}},"lastModified":"2026-05-28T14:34:48.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/rate-limits","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}