diff --git a/apps/docs/content/docs/developers/api/rate-limits.mdx b/apps/docs/content/docs/developers/api/rate-limits.mdx
index ecd50558e..e86dc0b1f 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/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..002cccd6e 100644
--- a/packages/lib/server-only/rate-limit/rate-limits.ts
+++ b/packages/lib/server-only/rate-limit/rate-limits.ts
@@ -84,19 +84,19 @@ 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',
});
export const apiTrpcRateLimit = createRateLimit({
action: 'api.trpc',
- max: 100,
+ max: 1000,
window: '1m',
});