Reference
Rate limits
Per-plan send caps, per-key request limits, and how the 429 response looks.
Bytloop enforces two independent limits: a monthly send cap on the
workspace (based on your plan) and a request-rate limit on every
API key. Both surface a 429 Too Many Requests when tripped, with a
Retry-After header telling you when to try again.
Monthly send cap#
The workspace-wide cap resets on the first day of each billing period. It counts every accepted send — bounced deliveries and suppressed recipients still count, since Bytloop still did the work to attempt them.
| Plan | Emails / month | Sending domains | Mailboxes |
|---|---|---|---|
| Free | 3,000 | 1 | 3 |
| Team | 50,000 | 5 | Unlimited |
| Scale | Custom | Custom | Unlimited |
Approaching the cap surfaces a banner in the dashboard and an email to
workspace admins at 80% and 100%. Requests over the cap are rejected
with 429, error code plan_cap_reached, until the next billing
period or a plan upgrade.
Per-key request rate#
Each API key has an independent request-rate budget so a runaway script using one key cannot starve a well-behaved one. Defaults:
| Plan | Requests / second per key | Burst |
|---|---|---|
| Free | 10 | 20 |
| Team | 50 | 100 |
| Scale | Negotiated | Negotiated |
The limiter is a token bucket, so short bursts up to the burst value are fine as long as the sustained rate stays under the per-second budget.
Batch endpoint#
Prefer POST /api/v1/emails/batch for high fan-out — up to 100
messages in a single request. Each message counts against the monthly
cap, but the batch itself is a single request against the per-second
budget.
429 response shape#
HTTP/1.1 429 Too Many Requests
Retry-After: 3
Content-Type: application/json
{
"error": {
"code": "rate_limited",
"message": "Request rate exceeded for this API key. Retry after 3 seconds.",
"retry_after_ms": 3000,
"correlation_id": "cor_2N9pKqRxLvZ8yT"
}
}Practical guidance#
- Move slow work off the request path. Enqueue sends in your own worker instead of firing them synchronously from a user's request — a spike in traffic then queues up behind your worker's rate instead of flooding Bytloop.
- Use idempotency keys on retries. Every 429 is safe to retry with
the same
Idempotency-Key; Bytloop will not double-send if the original request had already been accepted. - Split live and test traffic. Test keys have separate budgets, so a runaway CI job cannot starve your production send rate.
Next#
- Handle the wider set of failure modes in Errors.