# API rate limits

Every request to `/api` and `/mcp` counts against a budget. Signed-in requests
count against your account; anonymous requests count against your network
address. This page lists the limits, how to read them and what to do when you
hit one.

## Limits

| Policy      | Applies to                                                                                      | Limit                                                 |
| ----------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `api`       | Every signed-in API request and every signed-in MCP request                                     | 1,000 per 60 s, times your plan multiplier            |
| `api-heavy` | Expensive requests (compare, blame, code search, archives, pull request diffs), on top of `api` | 120 per 60 s signed in, times your plan; 10 anonymous |
| `api-anon`  | Every anonymous API and MCP request                                                             | 1,200 per hour per address                            |
| `feedback`  | Sending feedback through the API, on top of `api`                                               | 20 per day                                            |
| `web`       | Every web page load                                                                             | 3,600 per hour per address                            |

- Every credential of one account (browser session, personal access token,
  OAuth token, CLI login) shares one count.
- Anonymous requests are counted per IPv4 address or per IPv6 /64 network.
- Password Basic authentication uses the anonymous address budgets, including
  the reduced heavy-request limit, before password verification. It does not
  receive a per-account or plan-multiplied budget. A grant token sent as a Basic
  password uses the token budget instead.
- Git clone, fetch and push, and Git LFS, are not rate limited.

The [API reference](https://staging.git.cafe/api/openapi) marks each limited operation with its
policies in `x-gc2-ratelimit`.

## Plan multipliers

The `api` and `api-heavy` limits are multiplied by the highest
[plan](https://staging.git.cafe/docs/account/billing.md) among your personal account and the
organizations you are a member of. Outside collaborators do not get an
organization's plan. Anonymous, feedback and web limits are never multiplied.

| Plan          | Multiplier |
| ------------- | ---------- |
| Free          | 1×         |
| Pro           | 2×         |
| Team Standard | 5×         |
| Team Premium  | 10×        |
| Enterprise    | 20×        |

A plan or membership change takes effect within about 11 minutes.

## Read your limit

Successful responses carry the policies that were checked, with the quota `q`
and the window `w` in seconds:

```
RateLimit-Policy: "api";q=2000;w=60
```

The API does not report how many requests remain.

## Handle a 429

A request over its budget is refused with `429 Too Many Requests`:

```
HTTP/1.1 429 Too Many Requests
Retry-After: 17
RateLimit: "api-heavy";r=0;t=17
RateLimit-Policy: "api";q=1000;w=60, "api-heavy";q=120;w=60
Content-Type: application/problem+json

{
  "type": "https://cafe.sh/errors/rate-limit-exceeded",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "The api-heavy limit allows 120 requests per minute.",
  "policy": "api-heavy",
  "limit": 120,
  "window_seconds": 60,
  "retry_after_seconds": 17
}
```

1. Wait at least `Retry-After` seconds before retrying.
2. If the retry is limited too, back off further: limits use a sliding window,
   so a caller far over its budget can need more than one window to recover.
   An hourly or daily budget recovers gradually through the next hour or day.
3. Spread bulk work over time, sign in to get a per-account budget, or upgrade
   your plan for a higher multiplier.
