<!-- https://developers.silktide.com/v1/concepts/rate-limits | Concepts -->

# Rate limits

Silktide counts the requests each key makes to each path. A key can make **75 requests to the same path in five seconds**. The count starts with the first request and resets five seconds later, whatever happens in between.

The path is the whole path without the query string, so `/v1/websites/2` and `/v1/websites/3` are counted apart, and `/v1/results/scores?websiteId=2` and `/v1/results/scores?websiteId=3` are counted together.

## When you hit it

The 76th request gets `429`, with a `Retry-After` header giving the seconds until the count resets:

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 3
Content-Type: application/json

{
  "error": {
    "type": "TooManyRequests",
    "message": "You have exceeded the maximum number of requests allowed in a short period of time. Please try again later.",
    "properties": { "retryAfter": 3 }
  }
}
```

Wait that long and carry on. The body is the same shape as [other errors](https://developers.silktide.com/v1/concepts/errors.md), and `properties.retryAfter` repeats the header. If the count itself cannot be checked, Silktide answers `503` of type `ServiceUnavailable` the same way, with a `Retry-After` of a few seconds.

```javascript
async function silktide(url, init = {}) {
  for (;;) {
    const response = await fetch(url, {
      ...init,
      headers: { Authorization: `silktide token=${process.env.SILKTIDE_API_KEY}`, ...init.headers },
    });
    if (response.status !== 429 && response.status !== 503) return response;
    const seconds = Number(response.headers.get("Retry-After")) || 5;
    await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
  }
}
```

## Staying under it

- Ask for what you need once. [List websites and their sections](https://developers.silktide.com/v1/governance/websites/list-websites.md) answers for every website in one request.
- Poll slowly. A website's test takes minutes at least, so checking it every few minutes is plenty.
- Use one key per service. Keys that share a job do not share a limit, but spreading one job over many keys to dodge it can get them blocked.
