Error reference

temporarily_unavailable

HTTP 503 retryable: true REST and MCP

The request failed for a reason on this side rather than in your request, and the same call may succeed later without any change to it.

Why it happens

This is both a specific code and the catch-all. Any error that reaches the top-level handler without being an ApiError is logged and converted into this, with a 503 and the request id, because leaking an internal exception message to a caller is worse than a generic answer. It is also raised deliberately in several places where a dependency is missing rather than broken: rate-limiter bindings absent in production, an unconfigured database binding at the worker edge, billing not configured, the MCP token secret missing. Those are configuration states, not outages, and they do not resolve by retrying.

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. Retry with exponential backoff and jitter. This code carries retryable: true by default.
  2. Record x-request-id from the response before retrying. For the catch-all case that id is the only handle on what actually went wrong, because the detail stays server-side.
  3. Stop retrying after a few attempts if the message names a configuration state. Billing not configured and live send not enabled do not change between retries.
  4. Check the service status page if several unrelated calls fail this way at once.

Why it works this way

The rate limiter fails closed in production and open everywhere else. Allowing unmetered traffic through when the limiter is unavailable would remove the protection exactly when it is most likely to be needed, but applying the same rule locally would make development depend on infrastructure that has nothing to do with the code under test.

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

{
  "error": {
    "code": "temporarily_unavailable",
    "message": "The service is temporarily unavailable.",
    "request_id": "req_...",
    "retryable": true
  }
}

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