Rate Limiting
Named rate-limit buckets applied to the REST API, the MCP server, and the webhook surface.
Every authenticated API request sits behind at least one named limiter. Buckets apply per token, not per IP, because that's the unit of identity agents and Zaps share. Hit a limit and you'll get a 429 response wrapped in the standard error envelope with code: "RATE_LIMITED" plus a Retry-After header.
Named buckets
| Bucket | Applied to | Limit |
|---|---|---|
api-token | Every authenticated /v1/* route | 300 requests/min + 10,000 requests/hour |
api-ip (declared, not currently attached to any route) | Unauthenticated probes (/v1/ping, discovery endpoints) | 60 requests/min per IP |
access-codes-generate | POST /v1/projects/{project}/plans/{plan}/access-codes/bulk-generate | 10 bulk operations/min per token |
webhook-test | POST /v1/webhook-endpoints/{endpoint}/test | 5 test fires/min per endpoint |
mcp | Every request to mcp.subscriby.net (authenticated tool calls) | 120 tool calls/min per token |
mcp (unauth) | Same path, no token attached (probes, port scanners) | 5 requests/min per IP |
When the caller is unauthenticated (no token), the api-token limiter falls back to a per-IP key so accidental traffic bursts still get caught. The mcp limiter applies the same fallback but at a much tighter ceiling — unauthenticated traffic on the MCP surface is always either an exploration probe or a misconfigured client, never legitimate tool use, so the bucket is sized to fail fast rather than accommodate sustained calls.
Response headers
Every rate-limited response carries Laravel's standard rate-limit headers:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 278
Retry-After: 47Honour Retry-After before retrying — it reports the number of seconds until the bucket refills.
Error shape
{
"error": {
"code": "RATE_LIMITED",
"message": "The rate limit for this token has been exceeded.",
"remediation": "Back off and retry after the time hinted by the Retry-After header.",
"docs_url": "https://docs.subscriby.net/api/v1/errors#rate-limited",
"request_id": "00-abc..."
}
}Designing Zaps and agents
- Polling triggers: keep the interval ≥ 15 seconds per Zap. Zapier enforces this internally anyway.
- Bulk imports: chunk writes into batches of 100–200 and respect
Retry-Afterwhen a429fires. Concurrency doesn't beat the limiter — it counts concurrent calls the same as sequential ones. - MCP agents: assume the 120/min bucket is shared across every tool call in a session. Claude Desktop, Cursor, and VS Code throttle their own tool calls; hitting the limit in practice usually means a tight loop on your side.
- Bulk access-code generation: the 10/min bucket mirrors the rate applied in the dashboard. If you need more codes, raise each call's
quantityinstead of issuing more calls.
Upstream caps
The hourly api-token cap (10,000 requests) deliberately allows a sustained ~160 requests/min before the per-minute ceiling kicks in. If your integration needs a higher sustained rate, contact support — we don't publicly bump the default but can raise it per-token on request.
How is this guide?