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

# Rate Limits

> Understand request quotas and how to handle rate limiting.

The Matter API enforces per-user rate limits to ensure fair usage and protect the service.

## Limits

| Operation | Limit | Applies to |
| - | - | - |
| **Read** | 120 requests/min | All `GET` requests |
| **Write** | 30 requests/min | `POST`, `PATCH`, `DELETE` requests |
| **Save** | 10 requests/min | `POST /v1/items` (saving new URLs) |
| **Search** | 30 requests/min | `GET /v1/search` |
| **Markdown** | 20 requests/min | `GET` requests with `?include=markdown` |
| **Burst** | 5 requests/sec | All requests (short-term ceiling) |

Save requests have a lower limit because each save triggers background content extraction (fetching, parsing, and processing the URL). Markdown requests count against both the **read** and **markdown** limits because these responses are significantly larger and more expensive to serve.

Limits are applied per API token (i.e., per user account).

## Rate limit headers

Every response includes headers showing your current quota:

```
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1711814400
```

| Header | Description |
| - | - |
| `X-RateLimit-Limit` | Maximum requests allowed in the current window. |
| `X-RateLimit-Remaining` | Requests remaining in the current window. |
| `X-RateLimit-Reset` | Unix timestamp (seconds) when the window resets. |

## Handling 429 responses

When you exceed the limit, the API returns `429 Too Many Requests` with a `Retry-After` header:

```json theme={null}
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after 12 seconds."
  }
}
```

```
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711814400
```

### Recommended retry strategy

```python theme={null}
import time
import requests

def api_request(url, headers, max_retries=3):
    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", 10))
        time.sleep(retry_after)

    raise Exception("Rate limit exceeded after retries")
```

<Warning>
  Do not retry immediately or in a tight loop. Always respect the `Retry-After` value. Clients that ignore rate limits may have their tokens temporarily suspended.
</Warning>

## Best practices

<AccordionGroup>
  <Accordion title="Use incremental sync instead of full fetches">
    The `updated_since` parameter on list endpoints dramatically reduces the number of requests needed to stay in sync. Fetch everything once, then sync only changes.
  </Accordion>

  <Accordion title="Use larger page sizes">
    Set `limit=100` (the maximum) to reduce the number of requests needed to paginate through results.
  </Accordion>

  <Accordion title="Cache responses locally">
    Store items locally and only refetch when needed. The `updated_at` field tells you if an item has changed.
  </Accordion>

  <Accordion title="Batch your writes">
    If you're tagging many items, space your requests rather than firing them all at once.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.