Browse documentation

Tiers, quotas, and sandbox limits

Every account sends against a daily send cap plus a few per-tier resource limits (mailboxes, custom domains, webhook endpoints, retained storage). New accounts on the trial states (sandbox and pay-as-you-go) also ramp up gradually as they build a clean sending history. This page is the single source for those numbers and for the quota-preflight and rate-limit contracts you read back from the API.

At a glance

LimitSandboxPay-as-you-goStarterPro
Daily send cap15/day200/day (reputation cap; billed per send)233/day1,000/day
Mailboxes11525
Custom domains1113
Webhook endpoints13325
Retained storage1 GB5 GB5 GB15 GB

The daily send cap above is the tier ceiling. The value actually enforced on any given day is the effective cap, which the trial-state ramp (below) can hold lower until your account is established. Always read your live effective cap from GET /v1/accounts/quota rather than assuming the ceiling.

For sending volume beyond Pro, get in touch with the team.

Daily send cap and the new-sender ramp

  • Trial states (sandbox, pay-as-you-go) start at 15 sends/day and lift to 200/day once you have a clean send history. Sandbox's ceiling is 15/day, so a sandbox account stays at 15. Pay-as-you-go's ceiling is also 200/day — each send is still billed individually, but the daily cap is a reputation limit set deliberately below Starter's 233/day, so it stops rising once the ramp reaches it.
  • Subscription tiers (Starter, Pro) are coupled to their full ceiling immediately on your first cleared charge, regardless of the ramp. Starter = 233/day, Pro = 1,000/day.

The cap is a rolling per-UTC-day counter. It resets at midnight UTC.

Checking your quota

GET /v1/accounts/quota is an agent-safe preflight: it works with mailbox-scoped agent keys as well as admin keys and returns only send-budget fields (no account-wide detail). Call it before a batch of sends to see how much headroom is left today.

GET /v1/accounts/quota
Authorization: Bearer rly_live_<id>.<secret>
{
  "today": { "count": 12, "limit": 233, "day": "2026-07-02" },
  "sends_remaining": 221,
  "reset_at": "2026-07-03T00:00:00.000Z",
  "scope": "agent",
  "bound_mailbox_ids": ["<mailbox-uuid>"]
}
FieldMeaning
today.countSends already charged against today's budget (UTC).
today.limitYour effective daily cap — the number the send gate enforces today.
today.dayThe UTC budget day, YYYY-MM-DD.
sends_remainingmax(0, today.limit − today.count). Never negative.
reset_atISO-8601 UTC timestamp of the next midnight, when the budget resets.
scopeagent for a mailbox-scoped key, admin for an unrestricted key.
bound_mailbox_idsThe mailboxes an agent key is bound to (empty for an admin key).

Warm-up disclosure (present only when active)

When a new-sender warm-up applies to your account, the quota response carries an extra warmup object. Treat it as optional — branch on its presence, and when it is absent your full effective cap applies.

{
  "warmup": {
    "until": "2026-07-05T00:00:00.000Z",
    "shared_domain_daily_limit": 334,
    "velocity_gate_mode": "log_only",
    "reason": "New-sender warm-up protects your sending reputation on the shared pool. Verify your own domain for instant full volume."
  }
}
FieldMeaning
untilISO-8601 UTC timestamp when the warm-up window ends.
shared_domain_daily_limitThe reduced daily cap while warming up on the shared pool.
velocity_gate_modelog_only or enforced.
reasonHuman-readable explanation, including the escape hatch.

Verifying your own custom domain moves your sending to an isolated domain, which lifts the shared-pool warm-up.

When you hit the cap

Once today's budget is exhausted, send and reply calls return 429 with the code RATE_LIMITED and a details object you can use to schedule a retry:

HTTP/1.1 429 Too Many Requests

{
  "error": "Daily send limit reached",
  "code": "RATE_LIMITED",
  "details": {
    "daily_limit": 233,
    "sends_remaining": 0,
    "reset_at": "2026-07-03T00:00:00.000Z"
  }
}

sends_remaining is always 0 on this error (that is precisely why it fired), and reset_at tells you when the budget rolls over. Wait until reset_at rather than retrying immediately — a retry before the reset returns the same 429.

A RATE_LIMITED 429 may instead carry details.reason: "new_account_warmup" with a retry_after_seconds value when a new-sender warm-up throttle is in effect. Back off for that many seconds in that case.

A RATE_LIMITED 429 carrying details.reason: "failed_authentication" is not a send limit at all: it means your API key is wrong or revoked, and retrying will not help — see authentication.

RATE_LIMITED is only one of the send-gate outcomes. For everything else that can block a send (suppression, recipient containment, strict-recipient, MX validation, sandbox gates), see the send-gate decision tree; for the full error-code catalog, see the error reference.

Sandbox restrictions

Sandbox is the default trial state on signup. On top of the 15/day cap it adds:

  • A temporary trial address. Your sandbox mailbox's address lives on ReplyLayer's shared trial domain and is temporary to the trial — it isn't meant for production use. When you upgrade to a paid tier, you get your own dedicated platform subdomain (or bring your own domain) and choose the production identity your agent sends from going forward. Upgrading keeps the trial mailbox as a reply-only continuity mailbox: it stays active, keeps receiving inbound indefinitely, and can still reply to someone who has written to it in an existing thread, so nothing in flight is severed. What it cannot do is start a new thread — a fresh send from that mailbox returns 403 ESTATE_CONTINUITY_REPLY_ONLY. New email goes out from your sending mailbox, which is not restricted this way. Right after you upgrade, the billing page shows one setup form for it: you choose the name of your sending domain while it can still change, create the mailbox, add the people from your trial (and anyone else) to its approved list, and give your agent's keys and connected apps access to it, all with one save. Until then Overview and Connect Agent show a "Finish sending setup" link, and ReplyLayer's approval screen, when you connect an app through a sign-in flow, labels the trial mailbox as reply-only.
  • A cumulative trial budget of 250 total sends across the whole trial (not per day). When it is exhausted, sends return 403 SANDBOX_TRIAL_BUDGET_EXHAUSTED. Adding pay-as-you-go credits or upgrading to Starter clears it.
  • A 30-day trial clock.
  • One mailbox.
  • A recipient rule. On the free Sandbox you can email your own address and anyone who confirms by link, reply to people who write to you from an authenticated address, and add up to 5 people you know, yourself or through your agent. Add $5 of pay-as-you-go credit or upgrade to email anyone. In detail, a Sandbox send is admitted when its recipient is your account's own email address, a simulator scenario address, the sender of an inbound message you are replying to whose sender authentication passed, a recipient who confirmed by link, or a recipient you added as someone you know. Anything else is refused with 403 SANDBOX_RECIPIENT_NOT_VERIFIED before any send is counted (see the send-gate decision tree).
  • Adding people you know. Adding a recipient as someone you know (POST /v1/recipients with attest: true, or I know this person — add now on the dashboard's Recipients page) makes them sendable at once, with no email to them. A trial can do this for up to 5 people, shared between you and every agent key or app connection on the account, and deleting a recipient does not give one back. The allowance belongs to your verified phone number: a second Sandbox account on the same phone gets none of its own for 90 days. If someone added this way reports your email as spam, everyone added that way must confirm by link before you can email them again and your trial can no longer add people without confirmation; a report from a second person suspends the Sandbox account. GET /v1/auth/me reports how many are left in limits.sandbox_attestations_remaining.
  • A verified-recipient ramp. You can add up to 5 recipients in your first 72 hours, rising to 25 after that window; people you add as someone you know count toward it, and your own address does not. Exceeding the cap returns 403 TIER_LIMIT with a ramp_until timestamp. Each confirmation request or resend uses one of your 15 daily sends and counts toward the limit of 3 per recipient domain a day; a pending recipient can be resent at most twice in 24 hours, and adds plus resends are limited to 10 an hour.
  • A footer watermark appended to outbound messages. Sending from your own verified custom domain suppresses it.

The simulator exemption

Sends to simulator.replylayer.net addresses (delivered@, bounced@, complained@, suppressed@) — ReplyLayer's own first-party simulator — are exempt from the sandbox verified-recipient confirmation requirement (and are never auto-suppressed), so your onboarding test send in the quickstart works immediately without pre-confirming a recipient. The exact four scenario addresses and their +label forms also bypass the recipient-domain concentration cap below, so one Sandbox account can run all four in the same 24-hour period. Simulator sends still consume daily and cumulative Sandbox allowances, remain in the send-attempt ledger, and are subject to authentication, API rate limits, scanning and review policy, and idempotency. The exemption does not apply to another local part, subdomain, or lookalike domain. The email simulator guide defines each scenario and its billing, suppression, and reputation behavior.

Attachment capabilities by tier

Receiving attachments, their metadata, and viewing previews in the dashboard are available on every tier. The paid gates are:

CapabilitySandboxPay-as-you-goStarterPro
Receive attachments + metadata✓✓✓✓
Dashboard attachment preview✓✓✓✓
Agent-key preview API (derived text)—✓✓✓
Approved raw attachment download———✓
Outbound attachment sending———✓

A bound agent key on a tier without the agent-preview gate receives 403 ATTACHMENT_PREVIEW_DISABLED from the preview route. For the full staging → poll → attachment_ids → consume-once lifecycle and its failure codes, see attachments for agents.