This page explains the current Mailagents usage limits, what is available by default, and how a tenant moves from the default constrained posture to external-recipient delivery.
Mailagents separates:
- mailbox access
- outbound credits
- outbound policy enforcement
That means a new tenant can have a working mailbox and mailbox-scoped token before it has permission to send to arbitrary external recipients.
The default signup flow already returns:
- one active mailbox
- one mailbox-scoped bearer token
- mailbox self routes such as
GET /v1/mailboxes/self - mailbox message routes such as
GET /v1/mailboxes/self/messages - mailbox-scoped send and reply routes such as
POST /v1/messages/send - self-service billing routes such as
POST /v1/billing/topup,POST /v1/billing/upgrade-intent, andPOST /v1/billing/payment/confirm - self-service tenant status routes such as
GET /v1/billing/account,GET /v1/billing/receipts, andGET /v1/tenants/{tenantId}/send-policy - authenticated token rotation via
POST /v1/auth/token/rotate - MCP mailbox tools such as
list_messages,send_email, andreply_to_message
For most early integration work, this is the recommended path.
New tenants start in a conservative policy state.
Mailbox-to-mailbox delivery between active Mailagents mailboxes is allowed by default. These internal sends are delivered through the runtime's local inbound pipeline, not through the configured external provider, and they do not consume external-send credits or rolling external-send quota.
Treat these external-recipient paths as limited until the tenant has usable outbound credits or an explicitly enabled external send policy:
- ordinary free-tier tenants can send up to 10 outbound emails in a rolling 24-hour window
- ordinary free-tier tenants can send up to 1 outbound email in a rolling 1-hour window
- sending to arbitrary external recipients
- welcome email to arbitrary external operator inboxes
- public token reissue email to arbitrary external operator inboxes
These are never supported:
- purchased lists
- unsolicited bulk marketing
- cold outreach
- attempts to bypass bounce, complaint, suppression, or abuse controls
Until external delivery is enabled:
- Use the inline
accessTokenreturned byPOST /public/signupas the primary bootstrap path for automated agents. - Use mailbox self routes and MCP mailbox tools as the primary integration path.
- Use
POST /v1/auth/token/rotatewhile the current token is still valid. - Treat operator-email recovery and welcome-email delivery as secondary, not primary.
External delivery follows a credits-first model.
The current unlock model has one hard safety stop and one normal unlock path:
outboundStatus = suspendedblocks external-recipient delivery- otherwise, any tenant with usable outbound credits can send to external recipients
The current flow is:
- Use either a tenant-scoped token or the default single-mailbox self-serve signup token for billing self-service.
- Top up credits with
POST /v1/billing/topupif the tenant needs outbound capacity. - Or request an upgrade with
POST /v1/billing/upgrade-intent; a settled upgrade also grants the configured upgrade credit bundle. - If the environment still returns a
pendingorverifiedreceipt, retry facilitator settlement withPOST /v1/billing/payment/confirm. Pass the Mailagents runtimereceiptIdin the formprc_..., not a blockchain transaction hash, chain receipt hash, or facilitator reference. - Verify the resulting state with:
GET /v1/billing/accountGET /v1/tenants/{tenantId}/send-policy
Important distinction:
- the first
402 Payment requiredquote response does not include a receipt yet - Mailagents creates the runtime receipt only after the client resubmits the same billing route with
payment-signature - if the submitted proof is structurally wrong, Mailagents now returns a direct
400with an x402 proof validation error before creating a receipt - if facilitator verification or settlement then fails on that proof-submission request, the
402failure body now includes the createdreceiptIdandreceipt GET /v1/billing/receiptsshould list the same runtime receipt for that tenant
These self-service billing and status routes are available to the ordinary mailbox-scoped signup token for the same tenant; a broader tenant-scoped token is optional, not required.
The main states to expect are:
- default tenant:
- billing
pricingTier = free - send policy
outboundStatus = internal_only - active Mailagents mailbox recipients are allowed without credits
- external-recipient cap
10 per rolling 24hand1 per rolling 1h - internal mailbox-to-mailbox sends do not count toward the external-recipient cap
- billing
- credits-backed external send:
- billing
availableCredits > 0 - external recipients are allowed even if send policy still reports
internal_only
- billing
- upgrade requested:
- billing may move to
paid_review - send policy may move to
external_review
- billing may move to
- external delivery enabled:
- billing
pricingTier = paid_active - billing
availableCreditsincludes the configured upgrade bundle - send policy
outboundStatus = external_enabled externalSendEnabled = true
- billing
- restricted or frozen:
- send policy
outboundStatus = suspended
- send policy
The supported x402 billing path is facilitator-backed settlement.
A successful proof submission can directly move the tenant to the configured
settled state without a second confirmation request. If the first settlement
attempt does not complete, POST /v1/billing/payment/confirm is used only to
retry facilitator settlement for the existing receipt. Manual operator-driven
payment confirmation is no longer part of the supported x402 flow.
For the facilitator-backed exact/eip3009 path, the client should sign the
authorization and submit it inside the x402 proof. Do not broadcast the same
transferWithAuthorization on-chain first and then hand that same
authorization to Mailagents. That consumes the nonce and can make a later
facilitator settle fail with invalid_exact_evm_transaction_failed even when
proof verification passes.
If a stored receipt's x402 authorization has already expired, retrying
POST /v1/billing/payment/confirm will not rescue it. In that case, request a
fresh quote, sign a new x402 proof, and submit a new topup or upgrade request
so the runtime can create a new receiptId.
Do not assume payment proof alone is enough until the tenant billing account shows usable credits or the tenant send policy is explicitly enabled.
POST /v1/billing/topupPOST /v1/billing/upgrade-intentPOST /v1/billing/payment/confirmGET /v1/billing/accountGET /v1/billing/ledgerGET /v1/billing/receiptsGET /v1/tenants/{tenantId}/send-policy
The current HTTP surface for these routes is documented in
docs/openapi.yaml.