# Rate limits and quotas documented

> An agent that does not know the quota discovers it by being throttled, halfway through a task it cannot resume. The fix: document rate limits and quotas.

- Source: /checks/rate-limits-declared
- Site: AgenticWebScore
- Language: English

---
An agent that does not know the quota discovers it by being throttled, halfway through a task it cannot resume.

| Property | Value |
| --- | --- |
| Check id | `rate-limits-declared` |
| Dimension | Protocol Discovery (25%) |
| Tier | Recommended — pool 20 pts |
| Weight inside tier | 1 |
| Impact | Medium |
| Maturity | Experimental — An early convention that may still change shape. |
| Conditional | No |
| Publishing skill | `rate-limits` |
| Standards | RFC 9110 |

## What the scanner requests

- `/rate-limits.json`
- `/.well-known/rate-limits.json`
- `/docs/rate-limits`
- `/docs`

It also reads documents it has already fetched: `$home`.

## What is measured

The scanner makes one unauthenticated request to a public endpoint of the API and records any quota declaration the response carries (RateLimit or RateLimit-Policy, or the never-standardised X-RateLimit-* family), then reads the developer documentation and any machine-readable declaration the site links (/rate-limits.json, /.well-known/rate-limits.json and /docs/rate-limits) for a stated limit with its unit, its window, the scope it applies to and the behaviour when it is exceeded. It passes when the documentation states all four and a throttled response carries Retry-After, partially passes when limits are mentioned without numbers or windows, or when quota headers appear with nothing documented, and it is reported as not scored and excluded from the denominator unless the site has been positively identified as an API/developer platform.

## Reproduce it yourself

You do not have to take our word for any of this. Run the same measurement against your own domain:

```bash
DOMAIN=https://your-domain.example
{ curl -sS "$DOMAIN/rate-limits.json" | jq -c '{policies:[.policies[]?|{name,scope,limit,unit,window}],onExceeded}' 2>/dev/null || echo 'no rate-limits.json'; curl -sSL "$DOMAIN/docs/rate-limits" | grep -oiE '[0-9,]+ (requests?|calls?) per (second|minute|hour|day)|429|retry-after'; curl -sS -D - -o /dev/null "$DOMAIN/v1/ping" | grep -iE '^(HTTP/|ratelimit|retry-after|x-ratelimit)'; } | head -25
```

## The fix

This is the artifact to ship. It is the complete change, not a description of one.

```markdown
## Rate limits

Every endpoint is limited per API key; anonymous requests are limited per IP.

| Scope | Limit | Window | On exceed |
| --- | --- | --- | --- |
| API key | 1000 requests | 1 hour | 429 + Retry-After (seconds) |
| API key, burst | 20 requests | 1 second | 429 + Retry-After (seconds) |
| Anonymous, per IP | 60 requests | 1 minute | 429 + Retry-After (seconds) |

Responses carry `RateLimit-Policy` and `RateLimit`; a throttled request returns `429` (RFC 6585) with `Retry-After` (RFC 9110).
Machine-readable copy, linked from this page: https://your-domain.example/rate-limits.json
```json
{
  "version": 1,
  "policies": [
    { "name": "default", "scope": "per-api-key", "limit": 1000, "unit": "requests", "window": "1h" },
    { "name": "burst", "scope": "per-api-key", "limit": 20, "unit": "requests", "window": "1s" },
    { "name": "anonymous", "scope": "per-ip", "limit": 60, "unit": "requests", "window": "1m" }
  ],
  "onExceeded": { "status": 429, "retryAfter": "seconds" },
  "increase": "https://your-domain.example/docs/rate-limits#increases"
}
```
```

> No IETF standard covers a machine-readable quota declaration — RateLimit and RateLimit-Policy are still an Internet-Draft (draft-ietf-httpapi-ratelimit-headers, a WG document and not an RFC) and the widely deployed X-RateLimit-* family was never specified by anyone — so publish the numbers as this documented local convention and make the server actually enforce them, because a page that promises a limit the API does not return 429 with Retry-After for is worse for an agent than no documentation at all.

## Standards referenced

- `RFC 9110`

## Related checks

| Check | Tier | Impact | Same skill |
| --- | --- | --- | --- |
| `mcp-card` — MCP server card | Essential | High | — |
| `openapi` — OpenAPI definition | Essential | High | — |
| `oauth-discovery` — OAuth discovery documents | Essential | High | — |
| `api-catalog` — API catalog | Recommended | Medium | — |
| `agent-skills` — Agent Skills declaration | Recommended | Medium | — |
| `a2a-card` — A2A agent card | Recommended | Medium | — |
| `a2a-signed` — Cryptographically signed agent card | Emerging | Medium | — |
| `auth-md` — /auth.md agent authentication guide | Emerging | Medium | — |
