> ## Documentation Index
> Fetch the complete documentation index at: https://docs.opensourcemalware.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API rate limits

> Per-token, per-minute request limits, what happens when you hit your quota, and best practices for handling 429 responses.

The API enforces rate limits per API token, per minute. Limits vary by account tier. If you exceed your limit, the API returns a `429 Too Many Requests` response and you must wait until the next minute window before making additional requests.

## Limits by tier

| Account tier              | Requests per minute |
| ------------------------- | ------------------- |
| Free                      | 60                  |
| Researcher Pro/Enterprise | 180                 |

<Info>
  If your use case regularly approaches the Free limit (such as scanning large dependency graphs in CI or running a continuously updated security dashboard) consider upgrading to a paid account to get 180 requests per minute. Please note, this is only for organizations at this time. Paid accounts are not available for individuals. [Contact us](https://opensourcemalware.com/contact) to learn more.
</Info>

## What happens when you exceed the limit

When you send more requests than your tier allows within a one-minute window, the API responds with:

* **HTTP status**: `429 Too Many Requests`
* **Body**: a JSON object explaining the error

```json theme={null}
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Please wait before retrying."
}
```

## Best practices for staying within limits

<AccordionGroup>
  <Accordion title="Cache results">
    Threat data for a given resource does not change frequently. Cache the response from `check-malicious` locally (for example, for 24 hours) so you do not repeat identical lookups. This is especially effective in CI/CD pipelines where the same dependency list is scanned on every build.
  </Accordion>

  <Accordion title="Stagger automation">
    For automation that runs on a schedule (nightly scans, for example), spread requests evenly across the minute window rather than firing them all at once. A small `sleep` between requests keeps you well within your quota without sacrificing throughput.
  </Accordion>

  <Accordion title="Use exponential backoff on 429">
    When you receive a `429`, wait before retrying rather than retrying immediately. A simple exponential backoff strategy (wait 1 second, then 2, then 4, capping at a maximum) prevents a burst of retries from compounding the problem.
  </Accordion>

  <Accordion title="Batch lookups where possible">
    If you're scanning a dependency list, deduplicate it before sending requests. Checking the same package multiple times in a single scan wastes quota. Sort and deduplicate your input list before the scan loop.
  </Accordion>
</AccordionGroup>
