Pricing
Start free, with no card. Upgrade with one API call when an agent outgrows it.
| Free | Developer | Startup | Enterprise | |
|---|---|---|---|---|
| Price | $0 | $20/mo | $200/mo | Contact |
| Inboxes | 3 | 10 | 150 | Unlimited |
| Emails / month | 3,000 | 10,000 | 150,000 | Unlimited |
| Emails / day | 100 | Unlimited | Unlimited | Unlimited |
| Custom domains | 1 | 10 | 150 | Unlimited |
| Pods | 2 | 3 | 10 | Unlimited |
| Webhooks | 2 | 10 | 50 | Unlimited |
| Storage | 3 GB | 10 GB | 150 GB | Unlimited |
Every plan gets the whole API — REST and MCP, custom domains, threading, webhooks, attachments, suppression lists and the event log. The tiers differ in volume, not in features.
Start
Sign-up takes one call and needs no card. You get an address and an API key back; confirm the owner email and it can send.
curl -X POST https://api.carlyemail.com/v0/agent/sign-up \
-H 'content-type: application/json' \
-d '{"human_email": "you@pepsi.com", "username": "pepsi"}'
# → pepsi@carlyemail.com, plus an API key.
Upgrade
Ask for a checkout link and open it. Payment is handled by Stripe — we never see a card number.
curl -X POST https://api.carlyemail.com/v0/billing/checkout \
-H "authorization: Bearer $CARLYEMAIL_API_KEY" \
-H 'content-type: application/json' \
-d '{"plan": "developer"}'
# → {"checkout_url": "https://checkout.stripe.com/c/pay/..."}
The plan moves when Stripe confirms the subscription, not when the browser lands on the success page. New limits apply to the next request after that — there is nothing to redeploy and nothing to wait for.
Invoices, cards and cancellation
All three live in Stripe's billing portal. The same key opens it:
curl -X POST https://api.carlyemail.com/v0/billing/portal \
-H "authorization: Bearer $CARLYEMAIL_API_KEY"
# → {"portal_url": "https://billing.stripe.com/p/session/..."}
Cancelling drops you to the free tier at the end of the period. It does not delete anything: mail already in an inbox stays readable and searchable, and you keep every address you claimed. What changes is what you can add and how much you can send.
The portal needs a Stripe customer, so it answers
503 billing_unavailable for an account that has never
subscribed. There is nothing to manage until there is.
What a limit feels like
Nothing degrades quietly. Every cap refuses the request that would
cross it, with 429 and a code naming what ran out:
| When | Code |
|---|---|
| Too many inboxes | inbox_limit_reached |
| Too many domains | domain_limit_reached |
| Too many pods | pod_limit_reached |
| Too many webhooks | webhook_limit_reached |
| Daily send cap | daily_limit_reached |
| Monthly send cap | monthly_limit_reached |
| Storage full | storage_limit_reached |
Incoming mail is never refused for quota. An account over its storage allowance stops being able to send and keeps receiving — bouncing an arriving message would punish whoever wrote to you, who cannot see your plan and did nothing wrong.
GET /v0/organizations returns every count beside every
limit, so an agent can check before it is refused rather than after.
Enterprise
Higher volume, a dedicated sending domain, or terms your legal team wrote — talk to us. Enterprise is not self-serve on purpose: it is arranged, not purchased.