| name | clickup-rate-limits |
| description | Handle ClickUp API rate limits with backoff, queuing, and header monitoring.
Use when hitting 429 errors, implementing retry logic, or optimizing
API throughput against ClickUp's per-plan rate limits.
Trigger: "clickup rate limit", "clickup 429", "clickup throttling",
"clickup retry", "clickup backoff", "clickup request queue".
|
| allowed-tools | Read, Write, Edit |
| version | 1.6.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","productivity","clickup"] |
| compatibility | Designed for Claude Code |
ClickUp Rate Limits
Overview
ClickUp enforces per-token, per-minute rate limits that vary by Workspace plan. When exceeded, the API returns HTTP 429 with rate limit headers.
Rate Limit Tiers
| Workspace Plan | Requests/Min/Token | Burst Support |
|---|
| Free Forever | 100 | No |
| Unlimited | 100 | No |
| Business | 100 | No |
| Business Plus | 1,000 | Yes |
| Enterprise | 10,000 | Yes |
Rate Limit Headers
Every ClickUp API response includes these headers:
| Header | Description | Example |
|---|
X-RateLimit-Limit | Max requests in window | 100 |
X-RateLimit-Remaining | Requests left in window | 95 |
X-RateLimit-Reset | Unix timestamp when limit resets | 1695000060 |
Exponential Backoff with Jitter
async function clickupRequestWithRetry<T>(
path: string,
options: RequestInit = {},
config = { maxRetries: 5, baseDelayMs: 1000, maxDelayMs: 60000 }
): Promise<T> {
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
const response = await fetch(`https://api.clickup.com/api/v2`, {
...options,
: {
: process..!,
: ,
...options.,
},
});
(response.) response.();
(response. === ) {
resetTimestamp = response..();
: ;
(resetTimestamp) {
waitMs = .(, (resetTimestamp) * - .()) + ;
} {
exponential = config. * .(, attempt);
jitter = .() * ;
waitMs = .(exponential + jitter, config.);
}
.();
( (r, waitMs));
;
}
(response. < && response. !== ) {
error = response.().( ({}));
();
}
(attempt < config.) {
delay = config. * .(, attempt);
( (r, delay));
}
}
();
}