> ## Documentation Index
> Fetch the complete documentation index at: https://sendmux.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error codes and handling for the Sendmux API.

The Sendmux API uses standard HTTP status codes and returns a consistent error envelope so you can handle failures programmatically.

## Error response format

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "invalid_parameter",
    "message": "Description of the error.",
    "param": "from_date",
    "doc_url": "https://sendmux.ai/docs/api/errors#invalid_parameter",
    "retryable": false
  },
  "meta": {
    "request_id": "req_clxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}
```

| Field       | Description                                                                                                                             |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | Stable machine-readable code from the table below. Branch your client logic on this, not on the message text.                           |
| `message`   | Human-readable description suitable for logs or surfacing to internal tools. Wording may change without notice.                         |
| `param`     | Only present when the error is tied to a specific request field, usually the field that failed validation.                              |
| `doc_url`   | Anchor link into this page. Useful for surfacing inline help.                                                                           |
| `retryable` | `true` when the same request can succeed on a later attempt without changes. See [Retryable + Retry-After](#retryable--retry-after).    |
| `errors`    | Only present on accumulated validation failures. See [Validation errors with multiple issues](#validation-errors-with-multiple-issues). |

Every response also carries an `X-Request-Id` HTTP header that matches `meta.request_id` verbatim. Always include `request_id` when contacting support.

## Retryable + Retry-After

The `retryable` field tells you whether retrying the same request is likely to succeed. Defaults follow this policy:

| HTTP status | Default `retryable` | Why                                                        |
| ----------- | ------------------- | ---------------------------------------------------------- |
| `429`       | `true`              | Back off until the rate-limit window resets.               |
| `5xx`       | `true`              | Server-side issue or required service briefly unavailable. |
| `4xx` other | `false`             | Caller-side problem. Fix the request before retrying.      |

When `retryable` is `true` for a `429` or `503`, the response also carries a `Retry-After` HTTP header with the recommended wait in seconds. Honour that value rather than retrying immediately.

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json
```

A handful of codes override the default policy. `idempotency_conflict` is `false`: the client should either wait for the in-flight request to finish or use a fresh key for a different request.

## Validation errors with multiple issues

When a request body fails schema validation on multiple fields, the error envelope carries an `errors` array so you can surface every issue in a single round-trip.

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "invalid_parameter",
    "message": "Invalid request parameters.",
    "param": "filter_rules.0.action",
    "doc_url": "https://sendmux.ai/docs/api/errors#invalid_parameter",
    "retryable": false,
    "errors": [
      {
        "field": "filter_rules.0.action",
        "code": "invalid_enum_value",
        "message": "Expected 'allow' | 'deny'."
      },
      {
        "field": "filter_rules.2.pattern",
        "code": "too_small",
        "message": "String must contain at least 1 character(s)."
      }
    ]
  },
  "meta": { "request_id": "req_clxxxxxxxxxxxxxxxxxxxxxxxxx" }
}
```

The `param` at the top of the error matches the first issue's `field` for backwards compatibility. The full list lives in `errors[]`. Status is `400` for syntactic problems (`invalid_parameter`) and `422` for semantic violations (`validation_error`).

## Error codes

### authentication\_required

**HTTP 401**: The request has no `Authorization` header or the API key is invalid, expired, or revoked.

```bash theme={null}
# Fix: include a valid API key
curl https://app.sendmux.ai/api/v1/providers \
  -H "Authorization: Bearer smx_root_your_key_here"
```

### insufficient\_permissions

**HTTP 403**: The API key is valid but lacks the required permission for this endpoint. Check the [permission table](/docs/api/introduction#permissions) to see which permission each endpoint requires.

### invalid\_parameter

**HTTP 400**: A query parameter has an invalid format or value. The `param` field identifies which parameter is at fault.

### missing\_parameter

**HTTP 400**: A required query parameter is missing from the request.

### not\_found

**HTTP 404**: The requested resource does not exist, or it belongs to a different team than the one associated with your API key.

### conflict

**HTTP 409**: The request cannot be applied because of the resource's current state. Examples include deleting a domain while mailboxes still use it, creating a mailbox whose email address already exists, or sending a write with a stale `If-Match` header. Re-fetch the resource and reconcile before retrying.

### limit\_exceeded

**HTTP 409**: Your team has reached the create limit for this resource. This can apply to domains, mailboxes, sending accounts, webhooks, or active API keys. Request an increase from the relevant page in the Sendmux app, or delete an existing item before retrying. See [Team limits](/docs/guides/team-limits).

### idempotency\_conflict

**HTTP 409**: Returned when an `Idempotency-Key` request header is reused while the original request is still running, or with a request body whose fingerprint differs from the original. Wait and retry for an in-flight request. Use a fresh key for a different request. See the [Idempotency](/docs/guides/idempotency) guide.

### validation\_error

**HTTP 422**: A request body parsed cleanly as JSON but fails a semantic rule. Common cases include choosing an unsupported mailbox storage tier, shrinking mailbox storage below its current usage, referencing a provider or delivery group from a different team, or submitting more than 1,000 filter rules in a single request. The `param` field identifies the first offending field. The `errors` array lists every issue.

### rate\_limit\_exceeded

**HTTP 429**: You have exceeded the rate limit of 600 requests per minute. The response carries a `Retry-After` HTTP header with the recommended wait in seconds. Back off until then before retrying. `retryable` is `true`.

### payload\_too\_large

**HTTP 413**: The request body exceeds the server-side size limit. Trim the body or split it into smaller requests.

### service\_unavailable

**HTTP 503**: A required service is temporarily unavailable. The response may carry a `Retry-After` header. Requests are safe to retry with exponential backoff because `retryable` is `true`. If this persists for more than a few minutes, contact support with the `request_id` from the response.

### internal\_error

**HTTP 500**: An unexpected server error occurred. `retryable` is `true` because the failure is server-side. If it persists, contact support with the `request_id` from the response.
