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

# Understand error codes and what to do about them

> Error codes, HTTP statuses, causes, and recommended actions

Every mintfax API error returns a consistent JSON envelope. The `error` field is a stable, machine-readable code you can match on. The `message` field is human-readable. Most errors also include `action` (a programmatic hint for what to do next) and `docs` (a permalink back to this page).

Every error envelope also includes a `request_id` field matching the `X-Request-Id` response header. Include it when contacting support or filing a ticket. See [Request IDs](/troubleshooting#request-ids).

## Error response shape

```json theme={null}
{
  "error": "insufficient_balance",
  "message": "Insufficient balance for this operation.",
  "action": "top_up_balance",
  "docs": "https://mintfax.com/docs/errors/insufficient-balance",
  "request_id": "req_01J9XYZQ8KH7B3R0WXAZP8VW6F"
}
```

| Field        | Type   | Always present | Description                                                                   |
| ------------ | ------ | -------------- | ----------------------------------------------------------------------------- |
| `error`      | string | Yes            | Stable machine-readable code from the catalog below                           |
| `message`    | string | Yes            | Human-readable description                                                    |
| `action`     | string | Yes            | Programmatic next step (see per-code entries)                                 |
| `docs`       | string | Yes            | Permalink to the relevant entry on this page                                  |
| `request_id` | string | Yes            | The `req_*` ID for this request - quote it in support tickets                 |
| `context`    | object | No             | Extra fields specific to the error (e.g. validation details, balance amounts) |

Validation errors include a nested `context.errors` object with field-level messages. See [validation\_failed](#validation-failed) below.

***

## Error catalog

Each entry below is a stable error code returned in the `error` field. Anchors on this page match the code with hyphens (e.g. `/errors#insufficient-balance`).

<h3 id="validation-failed">
  `validation_failed`
</h3>

| HTTP | Action        |
| ---- | ------------- |
| 422  | `fix_request` |

The request body or query parameters failed validation. Check `context.errors` for per-field messages.

**When it fires:** A required field is missing, a field has the wrong type, or a value is outside its allowed range.

**What caused it:** The request payload does not satisfy the endpoint's validation rules. Common triggers: omitting `to` or `file` on `POST /fax`, sending a non-E.164 phone number, or exceeding the 10 MB file size limit.

**Next step:** Read `context.errors`, fix the flagged fields, and resubmit. The response body looks like this:

```json theme={null}
{
  "error": "validation_failed",
  "message": "The to field is required.",
  "action": "fix_request",
  "docs": "https://mintfax.com/docs/errors/validation-failed",
  "context": {
    "errors": {
      "to": ["The to field is required."],
      "file": ["The file must be a PDF, TIFF, or JPEG."]
    }
  }
}
```

***

<h3 id="unauthenticated">
  `unauthenticated`
</h3>

| HTTP | Action              |
| ---- | ------------------- |
| 401  | `check_credentials` |

No valid credentials were provided.

**When it fires:** The `Authorization` header is present but the value is not a recognized Bearer format, or the header contains a malformed value.

**What caused it:** The request included an `Authorization` header that could not be parsed as a Bearer API key.

**Next step:** Confirm the header value is `Bearer mfx_test_...` (sandbox) or `Bearer mfx_live_...` (live). Regenerate the API key in the dashboard if needed.

***

<h3 id="api-key-missing">
  `api_key_missing`
</h3>

| HTTP | Action              |
| ---- | ------------------- |
| 401  | `check_credentials` |

No `Authorization` header was sent.

**When it fires:** The request reaches the API gateway without an `Authorization` header.

**What caused it:** The HTTP client is not attaching the header. This is common when switching between sandbox and production base URLs and forgetting to set the header in the new environment.

**Next step:** Add `Authorization: Bearer <your-api-key>` to the request.

***

<h3 id="api-key-invalid">
  `api_key_invalid`
</h3>

| HTTP | Action              |
| ---- | ------------------- |
| 401  | `check_credentials` |

The API key was sent but is not recognized.

**When it fires:** The presented API key does not match any key on file.

**What caused it:** The API key was revoked, rotated, or copied incorrectly. Trailing whitespace and newline characters are common culprits when keys are pasted from a `.env` file.

**Next step:** Verify the API key in your dashboard. If it was rotated, use the new one. If you are unsure which environment you are targeting, sandbox keys start with `mfx_test_` and live keys start with `mfx_live_`.

***

<h3 id="forbidden">
  `forbidden`
</h3>

| HTTP | Action              |
| ---- | ------------------- |
| 403  | `check_credentials` |

The API key is valid but does not have permission to access this resource.

**When it fires:** The authenticated environment does not own the requested resource (e.g. fetching a fax that belongs to a different environment).

**What caused it:** A fax ID or resource ID from one environment was used with an API key from another environment.

**Next step:** Confirm you are using the correct API key for the environment that owns the resource. If you manage multiple environments, check that the fax ID matches the environment you are calling.

***

<h3 id="key-not-scoped-for-account">
  `key_not_scoped_for_account`
</h3>

| HTTP | Action            |
| ---- | ----------------- |
| 403  | `use_account_key` |

An environment key was used on an account-level route.

**When it fires:** A `mfx_test_...` or `mfx_live_...` key hits an account-management endpoint such as `/account/balance`, `/account/transactions`, or `/account/keys`.

**What caused it:** Environment keys (sandbox or live) are operational keys. They can send and read faxes inside an environment but cannot read or manage account-level resources. Account-level reads require an `mfx_acct_...` key.

**Next step:** Switch to your account-scoped key. The first acct key was returned at registration alongside the sandbox key; additional acct keys are created from the [dashboard](https://mintfax.com/dashboard). See [Keys](/keys) for the full scope matrix.

***

<h3 id="key-not-scoped-for-operations">
  `key_not_scoped_for_operations`
</h3>

| HTTP | Action                |
| ---- | --------------------- |
| 403  | `use_operational_key` |

An account key was used on an operational route.

**When it fires:** A `mfx_acct_...` key hits an operational endpoint such as `POST /faxes`, `GET /faxes/{id}`, or `GET /environment/*`.

**What caused it:** Account keys are admin keys for managing the account, not for sending or reading faxes. They cannot reach the operational surface.

**Next step:** Use a `mfx_test_...` (sandbox) or `mfx_live_...` (live) key for operational routes. See [Keys](/keys) for which key kind belongs on which endpoint.

***

<h3 id="acct-key-creation-dashboard-only">
  `acct_key_creation_dashboard_only`
</h3>

| HTTP | Action          |
| ---- | --------------- |
| 403  | `use_dashboard` |

Account-scoped keys cannot be created or deleted via the API.

**When it fires:** `POST /account/keys` with `scope_kind=account`, or `DELETE /account/keys/{id}` against an existing account-scoped key.

**What caused it:** Account-scoped keys are admin-equivalent for the entire account. Their lifecycle is intentionally restricted to the dashboard (a human-loop attestation step) so an API-only chain of compromise cannot escalate from a stolen environment key to full account control.

**Next step:** Create or revoke `mfx_acct_...` keys from the dashboard. Environment keys (`mfx_test_...` and `mfx_live_...`) can still be created and deleted via the API with an account key. See [Keys - Account keys](/keys#account-keys).

***

<h3 id="account-not-activated">
  `account_not_activated`
</h3>

| HTTP | Action             |
| ---- | ------------------ |
| 403  | `activate_account` |

The account has not completed the buy-as-activation flow, so live operations are blocked.

**When it fires:** A `mfx_live_...` key hits an operational route (`POST /faxes`, `GET /environment/*`, etc.) on an account whose `activated_at` timestamp is null.

**What caused it:** Live access requires a first successful credit purchase. The account exists, the key authenticates, but activation has not happened yet. See [Activation](/activation) for the full flow and the reasoning behind tying activation to a real purchase rather than just a saved card.

**Next step:** Log in to the [dashboard](https://mintfax.com/dashboard), click **Activate Live**, and complete the Stripe Checkout that captures the card and funds the first credit package. Activation is atomic with that purchase. Sandbox routes continue to work in the meantime.

***

<h3 id="not-found">
  `not_found`
</h3>

| HTTP | Action      |
| ---- | ----------- |
| 404  | `verify_id` |

The requested resource does not exist.

**When it fires:** A `GET`, `DELETE`, or `POST .../resend` targets a fax ID (or other resource ID) that does not exist in the current environment.

**What caused it:** The ID is wrong, the resource was deleted, or you are querying the sandbox environment for a fax that was sent in the live environment (or vice versa).

**Next step:** Double-check the resource ID. Confirm you are using the right API key for the right environment. If the fax was deleted via `DELETE /fax/{id}`, it is gone permanently.

***

<h3 id="insufficient-balance">
  `insufficient_balance`
</h3>

| HTTP | Action           |
| ---- | ---------------- |
| 402  | `top_up_balance` |

Not enough [credits](/credits) to complete this operation.

**When it fires:** `POST /fax` or `POST /fax/{id}/resend` is called and the environment's available balance (current balance minus outstanding holds) is less than the cost of the fax.

**What caused it:** The environment has run out of credits or has too many in-flight faxes holding credits. In the sandbox environment, the sandbox starts with a fixed credit balance that can be reset from the dashboard.

**Next step:** Purchase more credits in the dashboard or wait for in-flight faxes to complete (which releases their holds). Check `GET /account/balance` to see your current available balance.

***

<h3 id="fax-data-purged">
  `fax_data_purged`
</h3>

| HTTP | Action           |
| ---- | ---------------- |
| 422  | `submit_new_fax` |

The fax document data has been deleted and cannot be retrieved or resent.

**When it fires:** `GET /fax/{id}/image` or `POST /fax/{id}/resend` is called for a fax whose document data has been purged from storage.

**What caused it:** The fax reached a terminal state and the [data retention](/data-retention) window expired. If the environment uses zero-footprint mode, document data is deleted immediately after the fax reaches a terminal state.

**Next step:** Submit a new fax with the original document. The fax metadata record (`GET /fax/{id}`) is still available even after the document data is purged.

***

<h3 id="fax-not-terminal">
  `fax_not_terminal`
</h3>

| HTTP | Action                |
| ---- | --------------------- |
| 409  | `wait_for_completion` |

The fax has not yet reached a terminal state.

**When it fires:** `DELETE /fax/{id}` is called while the fax status is `queued`, `submitted`, or `in_progress`.

**What caused it:** You attempted to delete a fax that is still being processed. A fax must reach `delivered` or `failed` status before it can be deleted.

**Next step:** Poll `GET /fax/{id}` or listen for the terminal [event](/webhooks/events/overview) via your [webhook](/webhooks), then retry the delete. See the [glossary](/glossary) for definitions of fax statuses.

***

<h3 id="rate-limit-exceeded">
  `rate_limit_exceeded`
</h3>

| HTTP | Action           |
| ---- | ---------------- |
| 429  | `wait_and_retry` |

Too many requests in too short a window.

**When it fires:** The request rate for this API key exceeds the allowed threshold at the API gateway.

**What caused it:** Bursting too many requests. Automated retry loops without backoff are a common trigger.

**Next step:** Back off and retry with exponential delay. The `Retry-After` header (when present) tells you how many seconds to wait. If you consistently hit the limit, contact support to discuss a rate increase.

***

<h3 id="internal-server-error">
  `internal_server_error`
</h3>

| HTTP | Action                     |
| ---- | -------------------------- |
| 500  | `retry_or_contact_support` |

Something unexpected went wrong on the mintfax side.

**When it fires:** An unhandled exception or infrastructure failure occurs while processing the request.

**What caused it:** A bug or transient failure in the mintfax backend. Your request was valid.

**Next step:** Retry the request. If you included an `Idempotency-Key` header, the retry is safe to repeat without side effects. If the error persists, contact support with the request ID from the response headers.

***

## HTTP status code summary

| Code | Meaning                                                                     |
| ---- | --------------------------------------------------------------------------- |
| 200  | Success                                                                     |
| 201  | Resource created                                                            |
| 204  | Success, no content                                                         |
| 400  | Bad request (malformed JSON, wrong content type)                            |
| 401  | Missing or invalid API key                                                  |
| 402  | Insufficient balance                                                        |
| 403  | Forbidden, environment inactive, account not activated, or key scoped wrong |
| 404  | Resource not found                                                          |
| 409  | Conflict (resource not in expected state)                                   |
| 422  | Validation error, or fax data purged                                        |
| 429  | Rate limit exceeded                                                         |
| 500  | Internal server error                                                       |

***

## Related pages

* [Events](/webhooks/events/overview) - webhook event types and payloads
* [Glossary](/glossary) - definitions of fax statuses, environments, and other terms

<div style={{fontSize: "0.85rem", color: "gray", marginTop: "2rem"}}>
  Last updated: 2026-05-11
</div>
