> ## 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.

# Overview

> Make ACH payments to external party accounts

<Note>
  Direct is in early access and subject to change. To request Direct access, contact [hi@natural.com](mailto:hi@natural.com).
</Note>

An ACH payment (`ach_*`) pushes money from a [Wallet](/guides/concepts/wallets) to an [External party account](/guides/concepts/external-parties#external-party-accounts) over the ACH network.

| | |
| - | - |
| API | [ACH endpoints](/api-reference/ach/create-ach-payment) · [Errors](/api-reference/errors/ach) |
| Direction | `credit` (wallet → external account) |
| Currency | `USD` |
| Settlement | Asynchronous, in network batches |
| Reversible | Yes — the receiving bank can return a payment after settlement (`RETURNED`) |
| Headers | `Idempotency-Key` required on create and cancel; `X-Instance-ID` for [agent](/guides/concepts/agents) calls |
| Alternatives | [Realtime](/guides/concepts/realtime) and [Wire](/guides/concepts/wire) reach the same accounts faster and cannot be returned |

## Create

```json theme={null}
{
  "data": {
    "attributes": {
      "direction": "credit",
      "amount": 25000,
      "externalPartyAccountId": "epa_019cd1798d8e5a2f8ceb96020cc3991a",
      "companyEntryDescription": "PAYOUT"
    }
  }
}
```

* `companyEntryDescription` appears on the recipient's bank statement. It is limited to 10 characters and is trimmed and uppercased before submission. The response reports what was sent to the bank in `submittedDescriptor` (`companyName` and `companyEntryDescription`), along with the `secCode` used and, once submitted, the `traceNumber`.
* `addenda` is optional payment-related information carried to the receiving bank as a NACHA addenda record. It is limited to 80 characters and is trimmed before submission. Receivers that post payments from remittance data (for example tax agencies) read this field.
* The external party account does not need to be validated. Payments are accepted while validation is still `pending`.
* To send on behalf of a customer, pass `customerPartyId`. See [Move money for a customer](/guides/connect/move-money-for-customer).

## Lifecycle

| Status | Meaning | Terminal | Sets |
| - | - | - | - |
| `CREATED` | Accepted and waiting to be submitted | No | |
| `AWAITING_APPROVAL` | Held for [approval](/guides/concepts/approvals) after breaching a [limit](/guides/concepts/limits) | No | |
| `PROCESSING` | Submitted to the network | No | `submittedAt` |
| `SETTLED` | Settled by the receiving bank; a later return moves it to `RETURNED` | Yes | `settledAt`, `terminalAt` |
| `RETURNED` | Returned by the receiving bank | Yes | `return.*`, `terminalAt` |
| `APPROVAL_DENIED` | Approval was denied | Yes | `terminalAt` |
| `FAILED` | Failed before or during processing; details in `failure` | Yes | `terminalAt` |
| `CANCELED` | Canceled through the API | Yes | `terminalAt` |

`expectedAvailableAt` is an estimate and is `null` when unknown. When a payment is returned, `return` carries the NACHA `code` (for example `R01`), a `reason`, and the `returnedAt`, `dishonoredAt`, `contestedAt`, and `fundsUnlockedAt` timestamps.

**Cancel** — A payment can be canceled while it is `CREATED` or `AWAITING_APPROVAL`. Once submission starts, cancel returns `400 ach.not_cancellable`. Canceling emits no `ach.*` event.

**Events** — Status changes emit `ach.created`, `ach.processing`, `ach.settled`, `ach.failed`, and `ach.returned`. Approval holds emit `approval.*` events instead. The fee is assessed when the payment is submitted, so it's always null on `ach.created`. Read it from `ach.processing`. Payloads are documented in the [event catalog](/api-reference/event-catalog).


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