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

> ## Agent Instructions
> When building application code, use `@naturalpay/sdk` for TypeScript or `naturalpay` for Python.
> When operating Natural directly for a user, use the payments MCP at `https://mcp.natural.com`.
> When searching Natural documentation, use the docs MCP at `https://docs.natural.com/mcp`.
> Use the Natural CLI for terminal and CI automation.
> Use REST only for unsupported languages or when the user explicitly requests raw HTTP.
> Start integration development and testing in the sandbox. Do not use production unless the user explicitly requests it.
> For sandbox requests that require `customerPartyId`, list customers first. Reuse only the intended fixture; otherwise create a customer.
> REST and SDK amounts use integer minor units. Payments MCP amounts use decimal strings with a required currency code.

# Error handling

> Standard error format and recovery patterns

All Natural API errors follow a standard JSON:API-style format with stable public codes and safe display copy.

## Error response format

Every error response contains an `errors` array with one or more error objects:

```json theme={null}
{
  "errors": [
    {
      "code": "insufficient_funds",
      "detail": "Insufficient funds.",
      "status": "409",
      "meta": {
        "supportId": "req_a1b2c3d4e5f6"
      }
    }
  ]
}
```

Each error object contains:

| Field | Type | Required | Description |
| - | - | - | - |
| `code` | string | Yes | Stable public error code. Most are lower snake case (e.g., `insufficient_funds`); the ACH, realtime, and wire endpoints use dot-separated codes such as `wallet.required` |
| `detail` | string | Yes | Safe user-facing error message |
| `status` | string | Yes | HTTP status code as a string |
| `source` | object | No | Location of the invalid request value, such as `source.pointer` |
| `meta` | object | Yes | Metadata containing `supportId` for troubleshooting |

### Metadata

Public error responses include `meta.supportId` by default. Natural keeps internal detail in its logs, keyed by `supportId`. A rate-limited or capped request may also carry `meta.retryAfter` (an RFC 3339 timestamp) and, on a card payment cap, `meta.limitScope` (`merchant` or `program`). The exception is external account errors that can be repaired by relinking: those may also include `meta.connectionStatus` (`login_required` or `disconnected`) and `meta.provider` with the provider's error code, type, and request ID.

## Rate limit errors

Requests over the rate limit receive a `429` with code `rate_limited`. The response carries a `Retry-After` header with the seconds to wait before retrying. See [Rate limits](/api-reference/rate-limits).

## Validation errors

Validation responses contain one error object for each invalid request value. Each `detail` gives
a safe, schema-specific reason, while `source.pointer` identifies the exact location in the request.
`invalid_value` is `422` for a request-shape failure and `400` for a well-formed value the endpoint
cannot accept:

```json theme={null}
{
  "errors": [
    {
      "code": "invalid_value",
      "detail": "Too big: expected string to have <=80 characters",
      "status": "422",
      "source": {
        "pointer": "/data/attributes/description"
      },
      "meta": {
        "supportId": "req_a1b2c3d4e5f6"
      }
    },
    {
      "code": "invalid_value",
      "detail": "Invalid input: expected number, received string",
      "status": "422",
      "source": {
        "pointer": "/data/attributes/amount"
      },
      "meta": {
        "supportId": "req_a1b2c3d4e5f6"
      }
    }
  ]
}
```

## Cross-cutting errors

These errors depend on how a request is authenticated and attributed rather than on the resource being called, so the per-resource error pages do not list them. Most apply to requests made with agent credentials or on behalf of another party.

| Code | Status | Detail |
| - | - | - |
| `missing_instance_id` | 400 | X-Instance-ID is required for agent-attributed money movement. Send the X-Instance-ID header with a caller-chosen run/session identifier for this agent. |
| `account_closed` | 403 | This account has been closed. Contact support for assistance. |
| `account_frozen` | 403 | This account is temporarily frozen. Contact support for assistance. |
| `agent_wallet_access_no_access` | 403 | The agent does not have access to the selected wallet. |
| `card_acquiring_not_enabled` | 403 | Card acquiring is not enabled. |
| `delegation_required` | 403 | Acting on behalf of another party requires a valid delegation. To act through an agent, authenticate with that agent's key or an agent-scoped OAuth grant. |
| `kyc_rejected` | 403 | Identity verification was not approved, so this action is unavailable. Contact support for assistance. |
| `kyc_required` | 403 | Identity verification must be approved before this action is available. Finish onboarding to continue. |
| `voice_not_enabled` | 403 | Voice is not enabled. |
| `agent_wallet_access_wallet_required` | 422 | A wallet is required for this agent action. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.