Rate Limits
Learn about the rate limits for the Documenso Public API.
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
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.
Global per-IP 429 Response
{
"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.
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:
{
"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:
{
"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:
- The global per-IP limit, returning the
{ "error": "..." }body shown above. - Organisation windowed rate limits for the
api,document, andemailcounters. - Organisation monthly quotas for the same three counters. Every authenticated API request
consumes the
apicounter, so any endpoint can return this 429 once the monthly API quota is exhausted — not just envelope-related ones.
See Also
- Authentication - API authentication guide
- API Versioning - API version management
- First API Call - Getting started with the API
- Organisation Limits - Admins: set per-organisation resource quotas and rate limits (the HTTP rate limit above is separate and not admin-settable)