Rate Limits
Understand API rate limiting and how to handle 429 responses.
Rate Limits
The Templated API enforces rate limits to ensure fair usage and platform stability.
Current limits
| Endpoint category | Limit | Window |
|---|---|---|
| General API | 100 requests | Per minute |
| AI generation | 10 requests | Per minute |
| File uploads (images, fonts) | 30 requests | Per minute |
MCP endpoint (/api/mcp) — all messages | 60 requests | Per minute, per API key |
MCP endpoint — write tool calls (create_template, update_template, duplicate_template) | 20 calls | Per minute, per API key |
Rate limits are applied per account. All members of an account share the same rate limit pool. MCP limits are the exception: they are keyed to the individual API key, so one runaway agent can't exhaust another connector's quota.
MCP-specific responses
The overall MCP limit returns HTTP 429 with code MCP_RATE_LIMITED and a Retry-After header (seconds). The write limit returns a JSON-RPC error (code -32000) whose message states the retry delay — the HTTP response stays 200, since other messages in the batch may have succeeded. Both are safe to retry after the stated delay. See the MCP Server guide for details.
Rate limit headers
Every API response includes rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1707500000| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Handling rate limits
When you exceed the rate limit, the API returns a 429 Too Many Requests response:
{
"error": "Rate limit exceeded. Try again in 45 seconds."
}Best practices
- Check headers — Monitor
X-RateLimit-Remainingbefore making requests - Implement backoff — When you receive a 429, wait until
X-RateLimit-Resetbefore retrying - Batch operations — Where possible, batch multiple operations into fewer API calls
- Cache responses — Cache
GETresponses to reduce unnecessary calls
Retry strategy
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status === 429) {
const resetTime = response.headers.get("X-RateLimit-Reset");
const waitMs = resetTime
? (parseInt(resetTime) * 1000) - Date.now()
: 1000 * Math.pow(2, attempt);
await new Promise((resolve) => setTimeout(resolve, waitMs));
continue;
}
return response;
}
throw new Error("Max retries exceeded");
}Need higher limits?
Contact us at support@templated.email to discuss increased rate limits for your use case.