Requests & rate limits
The monthly request allowance, burst limits, overage, the quota headers and 429 handling.Updated October 25, 2026How requests are counted
Each plan comes with a number of requests per calendar month (UTC). One request is counted per fund found on GET /funds/{isin}, POST /funds, POST /portfolio and GET /overlap, whether the payload is served from the store (within its 24 hours or flagged stale: true) or loaded fresh. An ISIN with no fund data (404 fund_not_found) is not counted, up to 15 misses a month or the plan's allowance if larger, and is queued: FundFacts reloads it from the next daily run, then every 7 days (3 days when several accounts wait for it), tells you the estimated date in the 404 body (recheck.nextRecheckAt) and e-mails you when it is covered; Pro and up skip the wait by uploading the fund's own KID in the Factsheets tab. GET /funds/{isin}/history counts one request per call (Pro and up). /search, /resolve, /coverage, /watchlist, /changes, /me and the demo endpoint are free. Invalid ISINs, pending entries, and 401 / 429 responses never cost anything. Requests are counted per account, across all keys.
Plans
| Plan | Price | Requests / month | Burst / minute | Batch size | Beyond the allowance |
|---|---|---|---|---|---|
| Free | $0 | 5 | 10 | 1 | 429 until the reset |
| Starter | $9.99 / month | 60 | 30 | 10 | 429 until the reset |
| Pro | $49 / month | 1,000 | 120 | 50 | $0.05 per request, capped at $98.00 |
| Scale | $249 / month | 10,000 | 600 | 200 | $0.04 per request, capped at $498.00 |
| Enterprise | $0.01 / request | Unlimited (metered) | 1200 | 1,000 | $0.01 per request |
Overage lets Pro and Scale keep running after their monthly requests are used up: each extra request is billed on the next invoice ($0.05 on Pro, $0.04 on Scale), up to twice the plan price per month (ask us to raise the cap). Free and Starter stop at their allowance and answer 429 until the reset. Pricing has the full comparison.
Headers and the quota object
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests per month (absent on metered plans). |
X-RateLimit-Remaining | Requests left this month after this call; 0 while running on overage. |
X-RateLimit-Reset | Unix time (seconds) of the next monthly reset. |
X-Burst-Limit | Requests allowed per minute across all endpoints. |
X-Burst-Remaining | Requests left in the current minute. |
Retry-After | 429 only: seconds to wait (60 for a burst; until the reset when the monthly requests are used up). |
X-FundFacts-Stale | 1 when the body carries stale: true, a payload older than 24 hours refreshed in the background (GET /funds/{isin} only). |
Every successful response also carries a quota object: { limit, remaining, used, overageUsed, resetAt, burst: { limit, remaining } }.
Handling 429
A 429 rate_limited response carries reason: burst (slow down; retry after 60 seconds), quota_exhausted (Free and Starter: wait for the reset or upgrade) or overage_cap (paid plans: upgrade or contact us). When a bigger plan exists, upgrade names it with its allowance, price and URL, and message says what it gives, so a script or an agent can pass the offer on. Batch calls are refused as a whole when the remaining headroom is smaller than the number of ISINs sent, so nothing is half-charged.
429 Too Many Requests — json{"error": {"code": "rate_limited","message": "Monthly allowance of 5 requests used on the Free plan; resets 2026-10-01. Starter gives 60 requests a month for $9.99: https://fundfactsapi.com/dashboard/billing","plan": "free","reason": "quota_exhausted","limit": 5,"retryAfter": 1834000,"resetAt": "2026-10-01T00:00:00.000Z","upgrade": {"plan": "starter","name": "Starter","requests": 60,"price": "$9.99 / month","url": "https://fundfactsapi.com/dashboard/billing"}}}