diff --git a/concepts/rate-limits.mdx b/concepts/rate-limits.mdx index eecc620..d37e41e 100644 --- a/concepts/rate-limits.mdx +++ b/concepts/rate-limits.mdx @@ -27,15 +27,29 @@ This protects your domain reputation while it warms up. Relationship email (repl ## Rate limit responses -When rate limited, the API returns `429` with a `Retry-After` header: +When rate limited, the API returns `429` with a `Retry-After` header and a set of `X-RateLimit-*` headers describing the limit that was hit: + +| Header | Description | +|--------|-------------| +| `Retry-After` | Seconds to wait before retrying. | +| `X-RateLimit-Limit` | The limit that applied to this request. | +| `X-RateLimit-Remaining` | Requests remaining in the window (`0` on a 429). | +| `X-RateLimit-Reset` | Unix timestamp (seconds) when the window resets. | ```json { "error": "rate_limit_exceeded", + "scope": "burst", "message": "Max 10 sends per minute per inbox" } ``` +The `scope` field identifies which limit was hit: `burst`, `daily`, or `global` for send limits. The cold-outreach throttle returns `error: "cold_outreach_limit"` with `scope: "cold_outreach"`. Read `Retry-After` (or `X-RateLimit-Reset`) and back off until the window resets rather than retrying immediately. + + + These limits are mostly **per inbox** (burst, daily, cold outreach) plus a **per-account** daily send cap and inbox-creation cap. There is no fixed global "requests per minute" limit — pace your sends against the per-inbox limits above. Because limits are per inbox, you generally do not need multiple API keys to scale: spread load across inboxes instead. + + ## Why this matters Fresh domains on shared IP pools need time to build reputation. If your agents send too much cold outreach too quickly, emails will land in spam - which hurts your agents' effectiveness and your domain's reputation. These limits exist to protect deliverability. diff --git a/integrations/skill-files/api.mdx b/integrations/skill-files/api.mdx index 69b9a37..b15115d 100644 --- a/integrations/skill-files/api.mdx +++ b/integrations/skill-files/api.mdx @@ -245,11 +245,14 @@ Returns attachment data. Signed URL included in message payload — fetch prompt ## Rate limits -| Resource | Limit | -|---|---| -| Inbox creation | 100 per day | -| Send per inbox | 10 per minute, 200 per day | -| API requests | 1,000 per minute | +| Resource | Limit | Scope | +|---|---|---| +| Inbox creation | 100 per day | Per account | +| Send burst | 10 per minute | Per inbox | +| Send daily | 200 per day | Per inbox | +| Cold outreach (first 30 days) | 20 per day | Per inbox | + +There is no fixed global "requests per minute" limit. On a `429`, read the `Retry-After` and `X-RateLimit-*` headers and back off until the window resets. --- diff --git a/integrations/skill-files/errors.mdx b/integrations/skill-files/errors.mdx index 00b7d45..6a59011 100644 --- a/integrations/skill-files/errors.mdx +++ b/integrations/skill-files/errors.mdx @@ -78,10 +78,11 @@ Attachment URLs in inbound messages are signed and expire after a short window. ## Rate limits -| Resource | Limit | -|----------|-------| -| Inbox creation | 100 per day per account | -| Send per inbox | 10 per minute, 200 per day | -| API requests | 1,000 per minute per account | - -When rate limited, wait for the duration specified in the `Retry-After` header before retrying. +| Resource | Limit | Scope | +|----------|-------|-------| +| Inbox creation | 100 per day | Per account | +| Send burst | 10 per minute | Per inbox | +| Send daily | 200 per day | Per inbox | +| Cold outreach (first 30 days) | 20 per day | Per inbox | + +There is no fixed global "requests per minute" limit. When rate limited, the API returns `429` with `Retry-After` and `X-RateLimit-Limit` / `X-RateLimit-Remaining` / `X-RateLimit-Reset` headers, plus a `scope` field (`burst`, `daily`, `global`, or `cold_outreach`). Wait for the `Retry-After` duration before retrying.