# Rate limits

> The HubFit API allows 120 requests per minute per coach, plus a limit on messages. Read the RateLimit headers and back off on 429.

Source: https://hubfit.com/developers/rate-limits

## Limits

Each coach can make **120 requests a minute**, shared by all of that coach's API keys and connected apps, across the REST API and the [MCP server](https://hubfit.com/developers/mcp). Each team member has their own budget. If your workspace needs more, contact support.

[Sending messages](https://hubfit.com/developers/api/messages) has a limit of its own on top: **30 messages a minute and 500 a day** per coach, across the API and the MCP server. A send past it gets `429 rate_limited`, whose `detail` names the limit and when it resets.

## Rate limit headers

Every request that counts gets `RateLimit-Policy` and `RateLimit` headers ([IETF draft 8](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/)): the limit and its window in seconds, then what's left and the seconds until the window resets. Message sends also carry the `public-api-messages-minute` or `public-api-messages-day` policy.

Requests turned away before they're counted don't get them: a `401`, a `413`, a body that isn't valid JSON, and a `403` `plan_required`, `not_available`, `account_suspended` or `account_restricted`.

**Response headers**

```http
RateLimit-Policy: "public-api"; q=120; w=60
RateLimit: "public-api"; r=118; t=42
```

## Handling 429 responses

Past a limit, the API answers `429 rate_limited` with a `Retry-After` header in seconds. Wait that long, then retry. To stay under the limit, prefer [webhooks](https://hubfit.com/developers/webhooks) to polling, ask for up to 100 results a page, and use [client summaries](https://hubfit.com/developers/api/client-summaries) to compare clients.

**429 Too Many Requests (429 Too Many Requests)**

```json
{
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "Limit of 120 requests per minute reached. See the Retry-After header.",
  "requestId": "2f8e6c1a-4b7d-4e2a-9c3f-5d1b8a7e6f40"
}
```
