Per-IP limits, the headers that report them, what happens at 429, and how caching keeps most requests free.
| Surface | Limit | Window | Scope |
|---|---|---|---|
/api/v1/* | 120 requests | 60 s, sliding | per IP |
/api/mcp | 60 requests | 60 s, sliding | per IP |
/llms.txt | /llms-full.txt | no limit | - |
| Markdown mirrors | no limit | - | - |
The MCP limit is lower because tool calls always hit the database, whereas REST responses are served from the edge cache most of the time. Limits are generous for interactive agents; if you are building a bulk pipeline, use /llms-full.txt or paginate with limit=100.
HTTP/1.1 200 OK
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1790081905
Cache-Control: public, max-age=0, s-maxage=300, stale-while-revalidate=3600
Access-Control-Allow-Origin: *X-RateLimit-Reset is a Unix timestamp (seconds). Cached responses may carry slightly stale X-RateLimit-Remaining values; treat them as advisory.
HTTP/1.1 429 Too Many Requests
Retry-After: 15
Cache-Control: no-store
X-RateLimit-Remaining: 0
{
"error": {
"code": "rate_limited",
"message": "Rate limit of 120 requests per minute exceeded. Retry in 15s. Responses are cacheable - please cache them client-side."
},
"api_version": "1"
}On MCP the body is a JSON-RPC error (code: -32000) with the same message. Sleep for Retry-After seconds, then continue. Do not retry in a tight loop.
| Surface | Edge cache | Notes |
|---|---|---|
| /api/v1/products, /founders, /launches, /trending | 5 min | stale-while-revalidate for 1 h |
| /api/v1/products/{slug}, /founders/{username} | 5 min | Also refreshed instantly when the founder edits or an admin approves |
| /api/v1/categories | 10 min | Counts are live at generation time |
| /api/v1/openapi.json, /api/v1 | 1 h | Static |
| /llms.txt, /llms-full.txt | 1 h | Regenerated from live data |
| Markdown mirrors | 5 min | Same as the product page |
| MCP tool calls | none | Always live |
| Error responses | 404/400: 5 min · 429/500: never |
Cache on your side too.
Honour Cache-Control, key your cache on the full URL including query parameters, and use updated_at from product details to decide when a record is worth refetching.
Implementation note: limits are enforced per serving instance, so a burst spread across regions may be allowed slightly more than the nominal number. Treat the figures above as the guaranteed floor.