Error reference

payload_too_large

HTTP 413 retryable: false REST and MCP

The request carried more bytes than the limit for that kind of request, and it was stopped at the size check rather than being partially processed.

Why it happens

Size is counted as the body streams, not taken from Content-Length, because Content-Length can be absent, understated or simply wrong and a limit that trusts it is not a limit. The cap applied depends on the route: 1 MiB for a JSON body, 10 MiB for the binary upload route. Attachments are checked again later, both individually at 10 MiB and in aggregate at 15 MiB, and again at completion against the size that was actually declared and reserved, because the only number worth trusting is the one measured server-side.

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 which limit you hit before shrinking anything. A 1 MiB JSON cap and a 15 MiB attachment aggregate are different problems with different fixes.
  2. Declare the real byte length when reserving an upload. The completion check compares measured bytes against your declaration, so an understated declaration fails at the end rather than at the start.
  3. Keep the combined text and HTML body under 512 KB. That limit is enforced by the send schema and reports as invalid_request, not as this code.
  4. Link large files rather than attaching them. A send allows at most 10 attachments, each at most 10 MiB, totalling at most 15 MiB.

Why it works this way

Counting streamed bytes rather than reading Content-Length is the load-bearing detail. A client that omits the header, or understates it, would otherwise walk straight past a check that looks correct in the code.

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 413
content-type: application/json
x-request-id: req_...

{
  "error": {
    "code": "payload_too_large",
    "message": "Request body exceeds the allowed size.",
    "request_id": "req_...",
    "retryable": false
  }
}

Verified against packages/api/src/index.ts:73. 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