diff --git a/apps/docs/content/docs/developers/api/rate-limits.mdx b/apps/docs/content/docs/developers/api/rate-limits.mdx
index d2e31b1d4..95b0a68fe 100644
--- a/apps/docs/content/docs/developers/api/rate-limits.mdx
+++ b/apps/docs/content/docs/developers/api/rate-limits.mdx
@@ -11,9 +11,14 @@ Documenso enforces rate limits on all API endpoints to ensure service stability.
## HTTP Rate Limits
-**Limit:** 100 requests per minute per IP address
+**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.
+
+
### Rate Limit Response
```json
diff --git a/apps/docs/content/docs/developers/examples/common-workflows.mdx b/apps/docs/content/docs/developers/examples/common-workflows.mdx
index fe7887d5b..e0447d7c4 100644
--- a/apps/docs/content/docs/developers/examples/common-workflows.mdx
+++ b/apps/docs/content/docs/developers/examples/common-workflows.mdx
@@ -472,7 +472,7 @@ Send the same document to multiple recipients in parallel. Useful for policy ack
distributeDocument: true
- Process in batches with a short delay to respect rate limits (e.g. 100 requests/minute)
+ Process in batches with a short delay to respect rate limits (e.g. 1000 requests/minute)
@@ -638,8 +638,8 @@ done
- The API allows 100 requests per minute. For large batches, implement rate limiting with delays
- between requests to avoid hitting limits.
+ The API allows 1000 requests per minute (your organisation may have its own lower limit). For large
+ batches, implement rate limiting with delays between requests to avoid hitting limits.
---
diff --git a/apps/docs/content/docs/developers/getting-started/first-api-call.mdx b/apps/docs/content/docs/developers/getting-started/first-api-call.mdx
index 5ae0a6c67..665a90afd 100644
--- a/apps/docs/content/docs/developers/getting-started/first-api-call.mdx
+++ b/apps/docs/content/docs/developers/getting-started/first-api-call.mdx
@@ -483,7 +483,7 @@ The API returns standard HTTP status codes and JSON error responses:
### Handling Rate Limits
-The API allows 100 requests per minute per IP address. When rate limited, wait at least 60 seconds before retrying:
+The API allows 1000 requests per minute per IP address. Your organisation may have its own lower rate limits. When rate limited, wait at least 60 seconds before retrying:
```javascript
async function fetchWithRetry(url, options, maxRetries = 3) {
diff --git a/apps/docs/content/docs/policies/fair-use.mdx b/apps/docs/content/docs/policies/fair-use.mdx
index 0c4de348d..98d94dd5f 100644
--- a/apps/docs/content/docs/policies/fair-use.mdx
+++ b/apps/docs/content/docs/policies/fair-use.mdx
@@ -41,12 +41,17 @@ When a limit is reached, requests return a `429 Too Many Requests` response with
| Action | Limit | Window |
| --- | --- | --- |
-| API requests (v1 and v2) | 100 requests | 1 minute |
+| API requests (v1 and v2) | 1000 requests | 1 minute |
| File uploads | 20 requests | 1 minute |
| AI features | 3 requests | 1 minute |
Authentication endpoints (login, signup, password reset, etc.) are also rate-limited to protect against abuse.
+
+ The API request limit above is the global per-IP ceiling. Individual organisations also have their
+ own rate limits, which may be configured below this value.
+
+
Rate limits may vary by plan. Enterprise plans can include higher or custom limits. Contact
[sales](https://documen.so/sales) for details.
diff --git a/apps/docs/content/docs/self-hosting/configuration/organisation-limits.mdx b/apps/docs/content/docs/self-hosting/configuration/organisation-limits.mdx
index 2459812ce..c225975e5 100644
--- a/apps/docs/content/docs/self-hosting/configuration/organisation-limits.mdx
+++ b/apps/docs/content/docs/self-hosting/configuration/organisation-limits.mdx
@@ -13,7 +13,7 @@ There are three distinct kinds of limit:
| ---------------------- | ------------------------------------------------- | ----------------------- |
| Resource quota | Documents, emails, and API requests **per month** | Yes — per claim and org |
| Resource rate limit | The same resources over a short window (e.g. `1h`) | Yes — per claim and org |
-| Global HTTP rate limit | API requests per IP (100/min, hardcoded) | No — see [Limitations](#limitations) |
+| Global HTTP rate limit | API requests per IP (1000/min, hardcoded) | No — see [Limitations](#limitations) |
## Prerequisites
@@ -91,7 +91,7 @@ Monthly quota usage is keyed to the **UTC calendar month**. There is no schedule
## Limitations
-The **global HTTP rate limit is not configurable.** Documenso enforces a hardcoded **100 requests per minute per IP address** on its API endpoint groups (`/api/v1`, `/api/v2`, and the tRPC API are limited separately), returning `429 Too Many Requests`. It is a per-IP safeguard applied at the HTTP layer — not per-organisation, not stored on any claim, and not adjustable from the admin panel. See [Rate Limits](/docs/developers/api/rate-limits).
+The **global HTTP rate limit is not configurable.** Documenso enforces a hardcoded **1000 requests per minute per IP address** on its API endpoint groups (`/api/v1`, `/api/v2`, and the tRPC API are limited separately), returning `429 Too Many Requests`. It is a per-IP safeguard applied at the HTTP layer — not per-organisation, not stored on any claim, and not adjustable from the admin panel. See [Rate Limits](/docs/developers/api/rate-limits).
## Troubleshooting
diff --git a/packages/app-tests/e2e/api/v1/organisation-rate-limits.spec.ts b/packages/app-tests/e2e/api/v1/organisation-rate-limits.spec.ts
index d5e1fff6d..373f3738e 100644
--- a/packages/app-tests/e2e/api/v1/organisation-rate-limits.spec.ts
+++ b/packages/app-tests/e2e/api/v1/organisation-rate-limits.spec.ts
@@ -50,7 +50,7 @@ import type { Organisation, Team, User } from '@prisma/client';
*
* --- GLOBAL LIMIT AWARENESS ---
* apps/remix/server/router.ts applies a GLOBAL per-IP limiter to /api/v1/*:
- * apiV1RateLimit = 100 requests / 1 minute (action `api.v1`, see rate-limits.ts).
+ * apiV1RateLimit = 1000 requests / 1 minute (action `api.v1`, see rate-limits.ts).
* Every per-org limit/quota configured here is kept FAR below that ceiling (single
* digits) and the suite runs serially so the shared-IP global bucket is never the
* thing that trips. A global-limit 429 is shaped `{ error }` whereas an org-limit
@@ -62,7 +62,7 @@ const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
const baseUrl = `${WEBAPP_BASE_URL}/api/v1`;
// Run serially: all workers share one IP, and the global /api/v1 limiter is
-// per-IP. Serial execution keeps the shared global bucket well under 100/min.
+// per-IP. Serial execution keeps the shared global bucket well under 1000/min.
test.describe.configure({ mode: 'serial' });
// This suite is only meaningful with real rate limiting enabled. CI sets the
@@ -125,7 +125,7 @@ const setClaimLimits = async (team: Team, limits: ClaimLimits) => {
* GLOBAL /api/v1 IP bucket so a fresh scenario starts from zero.
*
* - The org windowed limiter keys its rows `ip:org:`.
- * - The GLOBAL limiter (apps/remix/server/router.ts -> apiV1RateLimit, 100/min
+ * - The GLOBAL limiter (apps/remix/server/router.ts -> apiV1RateLimit, 1000/min
* per IP, action `api.v1`) is shared by EVERY v1 request from this test client.
* Across the suite (and especially across repeated local runs within the same
* minute) that shared bucket would otherwise fill up and trip BEFORE the org
diff --git a/packages/app-tests/e2e/api/v2/organisation-rate-limits.spec.ts b/packages/app-tests/e2e/api/v2/organisation-rate-limits.spec.ts
index df261eb08..d64ab28c2 100644
--- a/packages/app-tests/e2e/api/v2/organisation-rate-limits.spec.ts
+++ b/packages/app-tests/e2e/api/v2/organisation-rate-limits.spec.ts
@@ -37,7 +37,7 @@ import type { Organisation, Team, User } from '@prisma/client';
*
* --- GLOBAL LIMIT AWARENESS ---
* apps/remix/server/router.ts applies a GLOBAL per-IP limiter to /api/v2/*:
- * apiV2RateLimit = 100 requests / 1 minute (see rate-limits.ts).
+ * apiV2RateLimit = 1000 requests / 1 minute (see rate-limits.ts).
* Every per-org limit/quota configured here is kept FAR below that ceiling (single
* digits) and the suite runs serially so the shared-IP global bucket is never the
* thing that trips. A global-limit 429 is shaped `{ error }` whereas an org-limit
@@ -49,7 +49,7 @@ const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
// Run serially: all workers share one IP, and the global /api/v2 limiter is
-// per-IP. Serial execution keeps the shared global bucket well under 100/min.
+// per-IP. Serial execution keeps the shared global bucket well under 1000/min.
test.describe.configure({ mode: 'serial' });
// This suite is only meaningful with real rate limiting enabled. CI sets the
diff --git a/packages/lib/server-only/rate-limit/rate-limits.ts b/packages/lib/server-only/rate-limit/rate-limits.ts
index 46233354c..5dfa47450 100644
--- a/packages/lib/server-only/rate-limit/rate-limits.ts
+++ b/packages/lib/server-only/rate-limit/rate-limits.ts
@@ -84,13 +84,13 @@ export const syncSubscriptionRateLimit = createRateLimit({
export const apiV1RateLimit = createRateLimit({
action: 'api.v1',
- max: 100,
+ max: 1000,
window: '1m',
});
export const apiV2RateLimit = createRateLimit({
action: 'api.v2',
- max: 100,
+ max: 1000,
window: '1m',
});