---
title: Rate Limits
description: Learn about the rate limits for the Documenso Public API.
---

import { Callout } from 'fumadocs-ui/components/callout';

## Overview

Documenso enforces rate limits on all API endpoints to ensure service stability.

## HTTP Rate Limits

The rate limit applies to:

- `/api/v1/*`
- `/api/v2/*`
- `/api/v2-beta/*`

**Limit:** 1000 requests per minute per IP address  
**Response:** 429 Too Many Requests

<Callout type="info">
  This is the global per-IP ceiling. Your organisation may have its own rate limits configured below
  this value, in which case you can be rate-limited before reaching the global limit.
</Callout>

### Global per-IP 429 Response

```json
{
  "error": "Too many requests, please try again later."
}
```

### Rate Limit Headers

Responses from `/api/v1/*`, `/api/v2/*`, and `/api/v2-beta/*` include these headers. The only
exception is CORS preflight (`OPTIONS`) requests, which are answered before the rate limiter runs
and carry no rate limit headers:

| Header                  | Description                                                            |
| ----------------------- | ---------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Maximum requests allowed in the current global window                  |
| `X-RateLimit-Remaining` | Requests remaining in the current global window                        |
| `X-RateLimit-Reset`     | End of the current global window, as a Unix epoch timestamp in seconds |

A 429 response from a windowed limiter also includes `Retry-After`, in seconds, with a minimum
value of `1`. The global API limit uses fixed, epoch-aligned one-minute buckets, so the actual wait
until the next window is between 1 and 60 seconds. Honor `Retry-After` exactly instead of sleeping
for a fixed 60 seconds. See the [Retry-After handling example](/docs/developers/examples/common-workflows#error-handling-patterns).

## Resource Limits

Beyond HTTP rate limits, your account has usage limits based on your subscription plan.

### Plan Limits

| Resource         | Free | Paid      | Self-hosted | Enterprise |
| ---------------- | ---- | --------- | ----------- | ---------- |
| Documents/month  | 5    | Unlimited | Unlimited   | Unlimited  |
| Total Recipients | 10   | Unlimited | Unlimited   | Unlimited  |
| Direct Templates | 3    | Unlimited | Unlimited   | Unlimited  |

### Organisation Limit 429 Responses

Organisation windowed limits and organisation monthly quotas produce 429 responses whose body
shape depends on the API version, and neither matches the global per-IP limiter's
`{ "error": "..." }` body.

On `/api/v1/*`, the body contains only a message:

```json
{
  "message": "Too many requests, please try again later. Contact support if you require higher limits."
}
```

On `/api/v2/*` and `/api/v2-beta/*`, the body is a structured error object:

```json
{
  "message": "Too many requests, please try again later. Contact support if you require higher limits.",
  "code": "TOO_MANY_REQUESTS",
  "data": {
    "code": "TOO_MANY_REQUESTS",
    "httpStatus": 429,
    "appError": {
      "code": "TOO_MANY_REQUESTS",
      "message": "Too many requests, please try again later. Contact support if you require higher limits."
    }
  }
}
```

Organisation windowed limit responses include the `X-RateLimit-*` headers and `Retry-After` for
their own window. Monthly quota responses carry no quota-specific rate limit headers or
`Retry-After` because the quota is not a time window; rely on the status code and message instead.

## Error Codes

| Code                | Status | Description                                                        |
| ------------------- | ------ | ------------------------------------------------------------------ |
| `TOO_MANY_REQUESTS` | 429    | Global per-IP, organisation windowed, or monthly quota exceeded    |
| `LIMIT_EXCEEDED`    | 400    | Resource usage limit exceeded                                      |

There are three sources of `TOO_MANY_REQUESTS` responses:

1. The global per-IP limit, returning the `{ "error": "..." }` body shown above.
2. Organisation windowed rate limits for the `api`, `document`, and `email` counters.
3. Organisation monthly quotas for the same three counters. Every authenticated API request
   consumes the `api` counter, so any endpoint can return this 429 once the monthly API quota is
   exhausted — not just envelope-related ones.

---

## See Also

- [Authentication](/docs/developers/getting-started/authentication) - API authentication guide
- [API Versioning](/docs/developers/api/versioning) - API version management
- [First API Call](/docs/developers/getting-started/first-api-call) - Getting started with the API
- [Organisation Limits](/docs/self-hosting/configuration/organisation-limits) - Admins: set per-organisation resource quotas and rate limits (the HTTP rate limit above is separate and not admin-settable)
