Sending
Sending limits
Three ceilings govern how much mail you can send, and they are independent. Your plan sets a monthly allowance. Your account’s sending history sets a daily cap. Underneath both, the platform itself has a daily ceiling on everything it sends from its shared IP. All three return 429, and the error.type tells you which one you hit.
Your monthly allowance
Each plan includes a number of messages per calendar month, counted in UTC. It counts accepted messages only: a send we refuse was never attempted, so it is never billed and never counted.
| Plan | Messages a month | Record retention |
|---|---|---|
| Free | 750 | 30 days |
| Starter | 100,000 | 90 days |
| Growth | 300,000 | 365 days |
| Scale | 1,000,000 | 730 days |
Exceeding it returns 429 with "type": "monthly_limit_reached" and a Retry-After pointing at the start of next month rather than at midnight. Moving to a larger plan lifts the ceiling immediately — there is nothing to wait for.
What else your plan caps
Volume is the limit most people meet, and it is not the only one. Everything the account can hold is capped too — templates, message streams, inbound addresses, seats, sub-accounts — along with how far back delivery analytics may look. Each is refused with 403 and its own error.type, carrying limit and used so a client can show “8 of 10” without parsing a sentence.
| Limit | Free | Starter | Growth | Scale | Enterprise |
|---|---|---|---|---|---|
| Emails a month | 750 | 100,000 | 300,000 | 1,000,000 | 1,000,000 |
| Sending domains | 1 | Unlimited | Unlimited | Unlimited | Unlimited |
| Record history | 30 days | 90 days | 1 year | 2 years | 2 years |
| Schedule ahead | 1 day | 3 days | 7 days | 14 days | 21 days |
| Templates | 3 | 25 | 100 | Unlimited | Unlimited |
| Message streams (incl. transactional) | 1 | 3 | 10 | 25 | Unlimited |
| Inbound addresses | Not included | 10 | 50 | 250 | 2,000 |
| Emails received a month | Not included | 50,000 | 200,000 | 750,000 | Unlimited |
| Verification codes a month | 100 | 5,000 | 25,000 | 100,000 | 100,000 |
| Address checks a month | 250 | 10,000 | 50,000 | 250,000 | 250,000 |
| Webhook endpoints | 1 | 3 | 10 | 25 | Unlimited |
| API keys | 5 | 15 | 40 | 150 | Unlimited |
| Contacts | 500 | 5,000 | 50,000 | 250,000 | Unlimited |
| Contact lists | 2 | 10 | 50 | Unlimited | Unlimited |
| Team seats | 1 | 3 | 10 | Unlimited | Unlimited |
| Sub-accounts | None | None | 5 | 25 | Unlimited |
| Delivery analytics window | 7 days | 30 days | 90 days | 90 days | 90 days |
The message-stream figure includes the stream you already have. Every account is created with a transactional stream, and it counts against the allowance — so a plan listing one stream is a plan on which POST /v1/streams refuses, by design. A stream is a suppression boundary, and an extra one is an extra way to keep mailing somebody who complained.
Enterprise figures are a floor. A negotiated agreement is stored per account and can raise any of them; it can never lower one below the published tier.
Your account’s daily cap
A new sending account has no history, and volume that appears out of nothing looks exactly like a compromised host to a receiving provider. So capacity is earned rather than granted. Every account starts at 50 messages a day and climbs one rung at a time, roughly doubling, over 10 rungs to a ceiling of 100,000 a day. Roughly doubling is the shape receivers are used to seeing from a business growing into its volume; a jump is the shape they filter.
| Rung | Daily cap |
|---|---|
| 0 | 50 |
| 1 | 200 |
| 2 | 500 |
| 3 | 1,000 |
| 4 | 2,500 |
| 5 | 5,000 |
| 6 | 10,000 |
| 7 | 25,000 |
| 8 | 50,000 |
| 9 | 100,000 |
How the cap moves
The review runs once a day, on your first send after midnight UTC, and looks only at the day before. It moves the cap by at most one rung in either direction.
- Up a rung after a day where you used at least 80% of your current cap, with a complaint rate at or under 0.1% and a bounce rate at or under 5%.
- Down a rung after a day where complaints passed 0.3% or bounces passed 10%.
- Held otherwise — including every idle day. Capacity is earned with real volume, not with time, or an account sending five messages a day would reach the top of the ladder in a fortnight with no reputation at all.
The complaint rate is the governor, not the calendar. The 0.3% figure is Gmail’s threshold, not ours — we stop growing and start shrinking well before a receiver would act on it. The step-up bar is deliberately stricter than the step-down bar: earning more volume should require a clean day, losing it should not require a disastrous one.
The review is hung off the send path rather than a scheduler on purpose. A cap that only moves when a cron job happens to be alive is a cap that silently stops adapting the first time that job dies.
The platform’s own daily ceiling
The ladder above is per account, and it cannot see the number a receiver actually forms an opinion about. Everyone’s mail leaves from one IP and one sending domain, so what Gmail and Microsoft judge is the total — not any one tenant’s share of it. Ten new accounts each entitled to a full first rung is ten times the first-day volume the warmup schedule promises, from an address with no history to spend.
So there is a second ceiling underneath yours: a cap on what the platform as a whole accepts in a UTC day, checked on every send after your own two limits. When it is reached, sends are refused with 429 and "type": "platform_paused" until the day rolls over or we raise the number.
platform_paused is not about your account, and it carries no account numbers — none of them are the reason. Nothing is wrong, nothing is lost, and no plan change affects it. Its Retry-After is short — 300 seconds — rather than a calendar boundary, because capacity frees up as the day’s total drains and as we lift the ceiling by hand; neither is a clock you could compute. Treat it as throttling to come back from, not as quota to alert on.
The number is raised deliberately, by us, as the IP earns reputation — not automatically on a timer. It is conservative on purpose: it is the one limit protecting the asset every account on the platform depends on.
What a 429 looks like
# 429
{
"error": {
"type": "daily_limit_reached",
"message": "This account has sent its daily limit of 1000 messages. …",
"limit": 1000,
"sentToday": 1000
}
}
# retry-after: 32219 (seconds until midnight UTC)
# 429
{
"error": {
"type": "monthly_limit_reached",
"message": "This account has used its monthly allowance of 750 messages …",
"limit": 750,
"sentThisMonth": 750
}
}
# retry-after: 1039821 (seconds until the 1st, UTC)
# 429 — ours, not yours. Carries no account numbers, because none of them
# are the reason.
{
"error": {
"type": "platform_paused",
"message": "We are holding sending briefly while this platform warms up …"
}
}
# retry-after: 300 (a few minutes, not a calendar boundary)Nothing over a cap is queued and delivered later. A refused message was never accepted, so it does not appear in your usage figures and is not billed.
A fourth kind of 429 exists and is unrelated to volume entirely: the request rate limit, type rate_limited. Branch on error.type, never on the status code alone — the four need four different responses.
Checking before you hit it
You do not have to wait for a 429 to find out where you stand. GET /v1/me returns sending.dailyLimit, sending.sentToday, sending.remainingToday, sending.warmupTier, sending.sentThisMonth and sending.remainingThisMonth.
GET /v1/usage returns the current period’s totals with the daily series behind them, so you can see which days produced a number rather than taking it on trust. Those counters are derived from the delivery record itself, not tallied separately, which is why they cannot drift from what actually happened.
The shared sending IP
Everything above is per account. Underneath it, the IP your mail leaves from is shared, and it is young — inbox placement is still being established. That is why the ladder is deliberately conservative and why bulk marketing mail is refused outright: on shared infrastructure one bad list damages placement for everybody on it. A broadcast to your own users is sent one message per recipient, and every one of those messages spends the same daily cap and monthly allowance as a single send.
See deliverability for what we can and cannot promise about placement.
NextWebhooks →Event payloads, signature verification over raw bytes, and the retry ladder.