Plans and limits

LimitFreeProScale
Price (USD, monthly / yearly)Free$19 / $190$79 / $790
Price (INR, monthly / yearly)Free₹1,499 / ₹14,990₹5,999 / ₹59,990
Inboxes325250
Sends per month30010,000100,000
Sends per day (whole org)100not capped separatelynot capped separately
Custom domains0110
Webhooks110100

Prices on this page are illustrative while the service is in early access. Receiving is not metered in v1. Yearly plans cost ten times the monthly price. On Pro and Scale, custom domains give you DNS record generation and verification; sending from and receiving on your own domain is not connected yet (see domains).

Enforcement#

When an action would exceed your plan, the API answers 402 with code plan_limit_exceeded, a fix message and the plan that would allow it. Limits apply to the organization, not to a pod: inbox count when you create an inbox, domain and webhook counts when you create those, and monthly and daily sends when you send. Sends are counted per unique recipient at send time, in UTC calendar months and days, so deleting an inbox does not reset usage and a send the provider rejects still counts.

GET /v0/billing returns your plan, status, limits and current usage; GET /v0/billing/usage returns just the limits and usage. In the dashboard, the Overview and Billing screens show the same numbers.

All limits#

LimitValue
Inboxes, sends per month, custom domains, webhooksBy plan (table above)
Sends per day, whole organization100 on Free, not capped separately on Pro and Scale
Sends per inbox100 in any rolling 24 hours by default, on every plan (429 rate_limited)
Recipients per message50 unique addresses across to, cc and bcc
Attachments per message50
Inline attachment content6 MB combined; use url for larger files
Attachment fetched by url10 MB per file, 25 MB total, https only, 10 second timeout
Request body40 MB
Page size (limit)1 to 100, default 50
Batch endpoints100 ids
Webhook scope ids10 per webhook (inbox ids, pod ids)
Webhook delivery10 second timeout, 8 attempts
Webhook signature tolerance5 minutes (recommended)
Idempotency keysKept 48 hours
Download links (raw, attachments)1 hour
Metrics windowstart within the last 90 days; at most 1000 buckets; at most 200,000 events scanned for rates
Requests per IP600 per minute
Requests per API key1200 per minute
/auth/* requests per IP30 per minute
MCP request body256 KB
Agent verification codeExpires in 24 hours, 10 attempts, human replaceable twice
Verification email linksExpire in 24 hours

Rate limits are counted in memory on a single server and reset when it restarts. Exceeding one returns 429 with Retry-After; see errors.

Billing#

  • Customers with an Indian billing country pay through Razorpay in INR; everyone else through Stripe in USD. You can override the choice at checkout.
  • GET /v0/billing shows the current plan, status, period end, limits and usage. POST /v0/billing/checkout returns a url to complete payment, POST /v0/billing/portal opens the Stripe customer portal (Razorpay has no hosted portal) and POST /v0/billing/cancel cancels at the end of the period. Billing routes need an organization-level key.
  • Your plan only changes when the payment provider's signed webhook says so; checkout alone grants nothing.
  • No free trial. A downgrade takes effect at the end of the paid period.
  • If a payment fails the plan becomes past_due. After a 7 day grace period Free limits apply.
  • Tax invoicing (GST or VAT) is not handled yet.
  • Early access: the checkout, portal and cancel code has been tested against simulated providers, not yet against live Stripe or Razorpay test accounts. See status.

Usage metrics#

GET /v0/metrics/usage returns time series for storage, messages, threads, inboxes, domains and pods at organization, pod and inbox level (needs metrics_read). GET /v0/metrics/events counts events by type. The dashboard overview draws them as charts. The Python SDK has methods for them; the TypeScript SDK has none for usage (it has metrics.rates).