Rate limits & quotas
Limits keep the service fast and free for everyone. They apply per network address without a key and per key with one.
| Tier | Per minute | Per day | Browser use |
|---|---|---|---|
| Anonymous (no key) | 30 | no daily quota | yes |
| Publishable key (sn_pk_) | 120 | 5,000 | yes |
| Secret key (sn_sk_) | 300 | 10,000 | no (refused) |
- Per-minute limits use a 60-second window at the edge.
- Daily quotas count every authenticated request per UTC day and reset at 00:00 UTC.
- Requests that fail validation still count towards the per-minute limit.
#Response headers
| Header | Meaning |
|---|---|
RateLimit-Policy | Your per-minute policy, e.g. 300;w=60 |
X-RateLimit-Limit | Requests allowed per minute for your tier |
X-Quota-Limit | Daily quota (keys only) |
X-Quota-Remaining | Requests left today (keys only) |
X-Quota-Reset | Seconds until the quota resets |
Retry-After | On 429: seconds to wait |
#Handling 429
Two different codes can come with 429:
| Code | Cause | What to do |
|---|---|---|
rate_limited | Too many requests this minute | Wait Retry-After seconds (60), then slow down |
quota_exceeded | Daily quota used up | Wait until 00:00 UTC; cache more aggressively |
A robust client retries rate_limited with exponential backoff and jitter:
async function getWithRetry(url, init = {}, tries = 4) {
for (let i = 0; ; i++) {
const res = await fetch(url, init);
if (res.status !== 429 || i === tries - 1) return res;
const body = await res.json();
if (body.code === 'quota_exceeded') return res; // do not retry until tomorrow
const wait = Number(res.headers.get('Retry-After') ?? 1) * 1000;
await new Promise((r) => setTimeout(r, wait + Math.random() * 1000 * 2 ** i));
}
}#Fair use
SENTINARA runs on free, shared infrastructure. Please:
- Cache. The data refreshes once a week (Mondays 02:17 UTC). Polling more often than every few hours gains nothing; check
GET /v1/statusfordata_updated_at. - Use list endpoints with
limitup to 500 instead of many single requests. - Download raw files for bulk analysis:
/v1/datasetslists every file with its SHA-256.
If total traffic exceeds the free capacity on a given day, the API may return errors until 00:00 UTC. Need more? Email api@sentinara.org with your use case.