# Rate limits

RateLimit and Retry-After headers on the FormsReach submit API so agents can self-throttle.

## What to expect

`POST https://api.formsreach.com/submit` is rate limited per form and per client. When you are close to the budget, or when a 429 is returned, read the response headers instead of retrying in a tight loop.

## Headers

| Header | When | How to use |
|---|---|---|
| `RateLimit` | Success and error JSON | IETF [RFC 9331](https://www.rfc-editor.org/rfc/rfc9331) remaining quota. Example: `100;w=60` means 100 requests in a 60 second window. |
| `RateLimit-Policy` | When advertised | The policy identifier for this form or IP. |
| `Retry-After` | HTTP 429 | Seconds to wait before the next POST. Treat this as authoritative. |

If a header is missing on a given response, back off exponentially (1s, 2s, 4s, cap 60s) and stop after a handful of retries. Do not hammer the endpoint from a retry storm.

## JSON 429 body

```json
{
  "data": null,
  "status": "failure",
  "error": {
    "type": "https://formsreach.com/errors/rate_limited",
    "title": "Too Many Requests",
    "status": 429,
    "code": "rate_limited",
    "detail": "This form or IP has exceeded the request rate limit."
  },
  "meta": { "requestId": "req_..." }
}
```

Resolution: wait for `Retry-After`, then retry the same payload once. Catalog: [rate_limited](/errors/rate_limited/).

## Related

- [Submit API overview](/docs/submit-api/overview/)
- [OpenAPI](/openapi.json)
- [Developers](/developers/)
