Error reference

payment_required

HTTP 402 retryable: false REST and MCP

The workspace is authenticated and permitted to make this call, but the capability it asks for is gated behind an entitlement that is not currently active.

Why it happens

Entitlement and permission are separate gates and they fail with separate codes. A 403 means the credential is not allowed to do this; a 402 means nothing about the credential is wrong and the workspace simply does not have the capability. The entitlement check reads live state each time: a paid subscription, an operational grant, or the complimentary live allowance. The free allowance is one live inbox and 100 email units a month per verified owner identity, claimed by that identity's first eligible workspace, and creating a second workspace does not mint a second allowance.

Every condition below was read in the implementation at the file and line given. They are the branches that raise this code, not a summary of what the name suggests.

How to fix it

  1. Check GET /billing/entitlement first. It reports what the workspace currently holds and is the only authoritative answer.
  2. For custom domains, there is no self-serve route today. Builder at $19/mo and Team at $79/mo are proposed plans at proposed prices and Stripe checkout is disabled, so a paid subscription cannot currently be started.
  3. If you are at the live inbox limit, delete an inbox you no longer use rather than creating another workspace. The complimentary allowance is per verified owner identity, so a new workspace does not renew it.
  4. Use a test project while you build. Test inboxes are free, capped at three active per workspace, and never consume email units.

Why it works this way

Receiving is not gated by this. When an allowance runs out, sending stops and mail that already arrived stays readable, because deleting or hiding received mail over a billing state would destroy data the customer already has.

Messages you will see

The message field is written for a human reading a log and is not a contract value. Branch on code instead. These are the exact strings this code is sent with today, listed so that a search for one of them lands here.

Where it appears

These are the documented surfaces that raise it. The REST base is https://api.emailforagents.ai/v1, and the remote MCP endpoint is https://mcp.emailforagents.ai/mcp.

The response

Read request_id off the body or the x-request-id header before doing anything else. It is the only handle on one specific attempt, and for a 503 it is the only handle at all, because the underlying detail stays server-side.

HTTP/1.1 402
content-type: application/json
x-request-id: req_...

{
  "error": {
    "code": "payment_required",
    "message": "A current paid subscription is required to resume sending.",
    "request_id": "req_...",
    "retryable": false
  }
}

Verified against packages/domain/src/billing.ts:702. The status comes from ERROR_STATUS in packages/contracts/src/errors.ts, which is the one place a code is mapped to a status.

All error codes · Documentation · Quickstart