# Rate limits

> Interpret configurable Hodoflow request windows, Retry-After responses, and the separate budgets for APIs and webhook ingestion.

Rate limits protect API and ingestion capacity. Values below are **defaults**,
not immutable product guarantees; deployments can configure them. Clients must
respond to the actual `429` and `Retry-After` header.

## Default windows

| Surface | Default | Key |
|---|---|---|
| JSON:API and authenticated GraphQL | 300 requests per 60 seconds | Service-account credential |
| Public/unauthenticated API probes | 300 requests per 60 seconds | Remote IP |
| Webhook ingestion | 100 deliveries per 60 seconds | Trigger token/path identity |

The window is fixed. One busy endpoint can consume the same credential budget
used by another endpoint, so coordinate concurrency across the integration.

## Rate-limit response

JSON:API and GraphQL transport limits return a stable API error and a header:

```http
HTTP/2 429
Retry-After: 17
x-request-id: <request-id>
```

```json
{
  "errors": [
    {
      "code": "rate_limited",
      "status": "429",
      "detail": "rate limit exceeded; retry after 17s",
      "meta": { "correlation_id": "<request-id>" }
    }
  ]
}
```

Webhook ingestion returns `429` with `Retry-After` and its simpler endpoint
error body. In both cases, the header governs recovery.

## Client behavior

1. Stop dispatching new work for the affected key.
2. Wait at least the stated number of seconds.
3. Resume gradually, not with the whole backlog at once.
4. Retry unsafe work with the same idempotency or delivery key.
5. Keep a bounded attempt/time budget and add jitter.

Do not guess the remaining window from local clocks. Do not retry every worker
independently. A shared limiter or queue per service account produces more
predictable throughput.

## Reduce request pressure

- Cache bearer tokens instead of exchanging per request.
- Use explicit, reasonable page sizes and follow pagination links.
- Request sparse fields and only required relationships.
- For GraphQL, select only consumed fields; narrower selections reduce both
  complexity and payload size.
- Deduplicate outbound webhook retries before they reach Hodoflow.
- Use exponential backoff for transient service failures as well as 429s.

For general retry classification, see [Idempotency and retries](/platform/idempotency-retries).
