Search documentation
Fuzzy search across every docs page and section
PlatformRate limits and quotas
Fuzzy search across every docs page and section
PlatformRate limits and quotas
Platform
Per-plan requests-per-second limits with 3x burst, monthly request and AI quotas, rate-limit headers, and 429 handling.
Two independent limits protect the platform: a per-second rate limit per API key (token bucket with 3x burst) and monthly quotas per application. Both return 429 rate_limit_error when exhausted.
| Plan | Price | Rate limit | Burst | API requests / mo | AI requests / mo | Connected users | Live access |
|---|---|---|---|---|---|---|---|
| Free | $0 | 10 rps | 30 | 10,000 | 1,000 | 100 | Test only |
| Startup | $99/mo | 50 rps | 150 | 500,000 | 50,000 | 5,000 | Yes |
| Growth | $499/mo | 200 rps | 600 | 5,000,000 | 500,000 | 50,000 | Yes |
| Enterprise | Custom | 1000 rps | 3000 | Custom | Custom | Custom | Yes |
Plans also set webhook endpoint and team member counts — see pricing. Upgrades apply immediately; quotas reset on the first of each month (UTC).
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Sustained rps for this key. |
X-RateLimit-Remaining | Tokens currently left in the bucket. |
X-RateLimit-Reset | Seconds until the bucket is completely full again. |
Back off and retry — the bucket refills within seconds. A minimal decorrelated backoff:
async function withBackoff<T>(fn: () => Promise<T>, maxAttempts = 5): Promise<T> {let delay = 500;for (let attempt = 1; ; attempt++) {try {return await fn();} catch (err) {const retryable =err instanceof FeelConnectError &&(err.type === "rate_limit_error" || err.type === "api_error");if (!retryable || attempt === maxAttempts) throw err;await new Promise((r) => setTimeout(r, delay + Math.random() * delay));delay = Math.min(delay * 2, 8000);}}}const page = await withBackoff(() =>fc.transactions.sync({ access_token: token }));
usage.limit_approaching webhook fires and a banner appears in the dashboard.429 rate_limit_exceeded until the month resets or you upgrade. Data is never deleted — only the API gate closes.