Headers
Every response carries:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Requests allowed per minute for this key |
X-RateLimit-Remaining |
Requests left in the current minute |
X-RateLimit-Reset |
When the minute resets, in epoch seconds |
Retry-After |
On a 429 only: seconds to wait |
The window is a fixed minute per key. A 429 costs no credits.
Other limits
| What | Limit |
|---|---|
GET /v1/public/stats (no key) |
30 requests a minute per IP; cacheable for an hour |
| New accounts (installgraph.com/login) | 3 per IP per day |
| Stores unlocked | 40,000 per account per 30 days (Credits) |
Need a higher rate? Talk to us.
Retrying
Retry 429 after Retry-After seconds, and 5xx with exponential backoff. Do not retry other 4xx: they fail the same way again.
async function call(url, init = {}, attempt = 0) {
const res = await fetch(url, {
...init,
headers: { Authorization: `Bearer ${process.env.INSTALLGRAPH_API_KEY}`, ...init.headers },
});
if ((res.status === 429 || res.status >= 500) && attempt < 5) {
const wait = Number(res.headers.get("Retry-After")) || 2 ** attempt;
await new Promise((r) => setTimeout(r, wait * 1000));
return call(url, init, attempt + 1);
}
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.error.message), body.error);
return body;
}
Billed requests are safe to retry: an error charges nothing, and a store you already paid for is free again for 7 days.