Rate Limits
Per-plan rate limits, headers, and retry guidance.
Rate limits are enforced per API key per rolling minute window. Read and write operations have separate limits.
Limits by plan
| Plan | Read (req/min) | Write (req/min) | Best for |
|---|---|---|---|
| Launch | 60 | 20 | Solo operators and early automations |
| Scale | 240 | 90 | High-velocity businesses and multiple workflows |
| Agency | 480 | 180 | Agencies and multi-client concurrent automations |
Read operations: GET endpoints (list posts, fetch post, list connections, usage).
Write operations: POST and PATCH endpoints (create post, upload media URL, webhooks).
Response headers
Every response includes current rate limit state:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 2026-02-17T14:00:00Z| Header | Value |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | ISO timestamp when the window resets |
Rate limit exceeded
When the limit is exceeded, the API returns 429 PUBLIC_API_RATE_LIMITED:
{
"success": false,
"error": {
"code": "PUBLIC_API_RATE_LIMITED",
"message": "Rate limit exceeded. Retry after the reset time."
}
}The response also includes a Retry-After header with the number of seconds to wait.
Recommended retry logic
async function callWithRetry(fn, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fn();
if (res.status !== 429) return res;
const retryAfter = parseInt(res.headers.get('Retry-After') || '5', 10);
if (attempt < maxRetries) {
await new Promise(r => setTimeout(r, retryAfter * 1000));
}
}
throw new Error('Rate limit retries exhausted');
}MCP tool calls
MCP tool calls share the same rate limits as the underlying API key. If you have multiple agents using the same key, their combined requests count toward the same limit. Use separate keys per integration to isolate limits.