> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mavioapp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limits

> Understand the rate limits applied to the Mavio API and how to handle them gracefully.

## Rate limit tiers

Rate limits are applied per API key and vary by plan. Limits are measured in requests per minute (RPM).

| Plan           | Rate limit         | Burst allowance            |
| -------------- | ------------------ | -------------------------- |
| **Free**       | 60 requests/min    | 10 extra for short bursts  |
| **Pro**        | 300 requests/min   | 50 extra for short bursts  |
| **Teams**      | 1,000 requests/min | 200 extra for short bursts |
| **Enterprise** | Custom             | Contact sales              |

<Note>
  Burst allowance lets you briefly exceed your base limit for short spikes. Sustained traffic above your base limit will still be throttled.
</Note>

## Rate limit headers

Every API response includes headers that tell you your current rate limit status:

| Header                  | Description                                             | Example      |
| ----------------------- | ------------------------------------------------------- | ------------ |
| `X-RateLimit-Limit`     | Maximum requests allowed per minute                     | `300`        |
| `X-RateLimit-Remaining` | Requests remaining in the current window                | `287`        |
| `X-RateLimit-Reset`     | Unix timestamp when the window resets                   | `1713000060` |
| `Retry-After`           | Seconds to wait before retrying (only on 429 responses) | `12`         |

```bash Example response headers theme={null}
HTTP/2 200
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1713000060
Content-Type: application/json
```

## Handling rate limits

When you exceed your rate limit, the API returns a `429 Too Many Requests` response:

```json 429 response theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "You have exceeded the rate limit of 300 requests per minute. Please retry after 12 seconds.",
    "request_id": "req_abc123def456"
  }
}
```

## Retry strategy

We recommend implementing exponential backoff with jitter when you receive a `429` response.

<CodeGroup>
  ```python Python theme={null}
  import time
  import random
  import requests

  def api_request_with_retry(url, headers, max_retries=5):
      for attempt in range(max_retries):
          response = requests.get(url, headers=headers)

          if response.status_code != 429:
              return response

          retry_after = int(response.headers.get("Retry-After", 1))
          jitter = random.uniform(0, 1)
          wait_time = retry_after + jitter

          print(f"Rate limited. Retrying in {wait_time:.1f}s (attempt {attempt + 1})")
          time.sleep(wait_time)

      raise Exception("Max retries exceeded")
  ```

  ```javascript Node.js theme={null}
  async function apiRequestWithRetry(url, headers, maxRetries = 5) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await fetch(url, { headers });

      if (response.status !== 429) {
        return response;
      }

      const retryAfter = parseInt(response.headers.get('Retry-After') || '1', 10);
      const jitter = Math.random();
      const waitTime = (retryAfter + jitter) * 1000;

      console.log(`Rate limited. Retrying in ${(waitTime / 1000).toFixed(1)}s (attempt ${attempt + 1})`);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }

    throw new Error('Max retries exceeded');
  }
  ```
</CodeGroup>

## Best practices

<AccordionGroup>
  <Accordion title="Cache responses when possible">
    Meeting data and transcripts rarely change. Cache responses on your side to reduce the number of API calls. Use the `ETag` header for conditional requests.
  </Accordion>

  <Accordion title="Use webhooks instead of polling">
    Instead of polling for new meetings or transcripts, set up [webhooks](/api-reference/webhooks/overview) to receive real-time notifications when data is ready.
  </Accordion>

  <Accordion title="Batch your requests">
    When fetching multiple resources, use list endpoints with appropriate `limit` values instead of making individual requests for each item.
  </Accordion>

  <Accordion title="Monitor your usage">
    Check the `X-RateLimit-Remaining` header proactively and throttle your requests before hitting the limit.
  </Accordion>
</AccordionGroup>

## Endpoint-specific limits

Some resource-intensive endpoints have additional per-endpoint limits regardless of your plan:

| Endpoint                         | Limit           | Notes                                          |
| -------------------------------- | --------------- | ---------------------------------------------- |
| `POST /transcripts/search`       | 30 requests/min | Full-text search is computationally expensive  |
| `POST /summaries/:id/regenerate` | 10 requests/min | AI regeneration consumes significant resources |
| `POST /oauth/token`              | 20 requests/min | Prevents brute-force token attempts            |

<Tip>
  Need higher limits? [Contact our sales team](mailto:sales@mavioapp.com) about Enterprise plans with custom rate limits and dedicated infrastructure.
</Tip>
