---
title: "Create ACH payment"
method: POST
path: "/ach"
tags: ["ACH"]
---

# Create ACH payment

`POST /ach`

Create an ACH payment to an external party account

## Headers

- `Idempotency-Key` string, required
- `X-Instance-ID` string, nullable

## Request body

- object
  - `data` object, required
    - `attributes` object, required
      - `customerPartyId` string — Customer party to act for (pty_*). Omit to act as your own party. To act for another party, pass the ID of a party that has authorized you to act on its behalf.
      - `direction` 'credit', required — Direction of the payment.
      - `amount` integer, required — Amount in cents.
      - `currency` 'USD' — Currency code. Defaults to USD.
      - `walletId` string — Wallet (wal_*) that funds an ACH credit or receives an ACH debit. Omit to use the party default for user or party API calls, or the agent default for the current customer connection when acting through a connected agent. Owned agents use their own agent default.
      - `externalPartyAccountId` string, required — External party account (epa_*) to pay.
      - `companyEntryDescription` string, required — ACH company entry description. Delivered to the receiving bank on the entry. Maximum 10 characters.
      - `internalDescription` string — Description for your internal reference. Never shared with the counterparty or the banking network. Maximum 255 characters.
      - `addenda` string — Payment-related information carried to the receiving bank as the NACHA addenda record. Maximum 80 characters.

## Response `201`

Successful Response

- object
  - `data` object, required
    - `type` 'ach', required — Resource type. Always `ach`.
    - `id` string, required — ACH payment ID (ach_*).
    - `attributes` object, required
      - `direction` 'credit', required — Direction of the payment.
      - `amount` integer, required — Amount in cents.
      - `currency` 'USD', required — Currency code.
      - `fee` object, nullable, required — Fee added to your cost as the sender. Null when no fee applies, the fee was voided, or your party is not the fee payer.
        - `amount` integer, required — Fee amount in cents.
        - `currency` 'USD', required — Currency of the fee.
        - `payer` 'sender', required — Party role charged the fee.
        - `applied` 'on_top', required — The fee is added to the sender's cost without reducing the principal amount.
      - `status` 'CREATED' | 'AWAITING_APPROVAL' | 'APPROVAL_DENIED' | 'PROCESSING' | 'SETTLED' | 'FAILED' | 'RETURNED' | 'CANCELED', required — ACH payment status, in lifecycle order: CREATED, AWAITING_APPROVAL, PROCESSING, SETTLED; APPROVAL_DENIED, FAILED, RETURNED, or CANCELED end it.
      - `companyEntryDescription` string, required — The company entry description requested at creation. Echoes the create input verbatim; see `submittedDescriptor` for what was sent to the bank.
      - `internalDescription` string, nullable, required — Description for your internal reference, or null. Never shared with the counterparty or the banking network.
      - `addenda` string, nullable, required — Payment-related information carried to the receiving bank as the NACHA addenda record, or null when none was provided.
      - `secCode` 'WEB' | 'PPD' | 'TEL' | 'CCD', required — ACH SEC code the entry is submitted under: WEB, PPD, TEL, or CCD.
      - `submittedDescriptor` object, required
        - `companyName` string, required — Company name submitted on the ACH payment.
        - `companyEntryDescription` string, required — Company entry description submitted on the ACH payment.
      - `traceNumber` string, nullable, required — ACH trace number assigned at submission, or null before submission.
      - `failure` object, nullable, required — Failure details when the payment failed, or null.
        - `reason` string, nullable, required — Failure reason, or null.
        - `code` string, nullable, required — Failure code, or null.
      - `return` object, nullable, required — Return details when the payment was returned, or null.
        - `code` string, required — ACH return code, such as R01.
        - `reason` string, nullable, required — Return reason, or null.
        - `returnedAt` string, required — RFC 3339 timestamp when the return was received.
        - `dishonoredAt` string, nullable, required — RFC 3339 timestamp when the return was dishonored, or null.
        - `contestedAt` string, nullable, required — RFC 3339 timestamp when the dishonor was contested, or null.
        - `fundsUnlockedAt` string, nullable, required — RFC 3339 timestamp when the returned funds were released, or null.
      - `submittedAt` string, nullable, required — RFC 3339 timestamp when the payment was submitted to the bank, or null.
      - `settledAt` string, nullable, required — RFC 3339 timestamp when the ACH payment settled, or null. A return can still arrive after settlement.
      - `expectedAvailableAt` string, nullable, required — RFC 3339 timestamp when the funds are expected to be available, or null when unknown.
      - `terminalAt` string, nullable, required — RFC 3339 timestamp when the payment reached a terminal status, or null.
      - `createdAt` string, required — RFC 3339 timestamp when the ACH payment was created.
      - `updatedAt` string, required — RFC 3339 timestamp when the ACH payment was last updated.
    - `relationships` object, required
      - `customerParty` object, required — Party the payment was created for.
        - `data` object, required — Related resource identifier.
          - `type` 'party', required — Resource type. Always `party`.
          - `id` string, required
      - `wallet` object, required — Wallet used for this payment.
        - `data` object, required — Related resource identifier.
          - `type` 'wallet', required — Resource type. Always `wallet`.
          - `id` string, required
      - `externalParty` object, required — External party the payment is with.
        - `data` object, required — Related resource identifier.
          - `type` 'external_party', required — Resource type. Always `external_party`.
          - `id` string, required
      - `externalPartyAccount` object, required — External party account used.
        - `data` object, required — Related resource identifier.
          - `type` 'external_party_account', required — Resource type. Always `external_party_account`.
          - `id` string, required

## Other responses

- `400` — Validation Error
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found. Returned when the resource does not exist, or when it exists but is not accessible to your account. The two cases are intentionally indistinguishable, so that resource IDs cannot be enumerated by probing.
- `409` — Conflict
- `422` — Validation Error. The response contains one error object for each invalid request value.
- `428` — Precondition Required
- `429` — Too Many Requests
- `500` — Internal Server Error
- `501` — Not Implemented
- `502` — Bad Gateway
- `503` — Service Unavailable

## Changes

- **2026-09-24** `e79d669f0234` — 2 breaking, 1 warning, 3 info
  - removed the enum value `debit` of the request property `data/attributes/direction`
  - removed the required property `data/relationships/mandate` from the response with the `201` status
  - removed the request property `data/attributes/mandateId`
  - added the new optional request property `data/attributes/internalDescription`
  - …2 more
- **2026-09-23** `bcf3b028c3e5` — 1 info
  - added the required property `data/attributes/fee` to the response with the `201` status
- **2026-09-19** `7dd2420be291` — 2 info
  - added the new optional request property `data/attributes/addenda`
  - added the required property `data/attributes/addenda` to the response with the `201` status
- **2026-09-02** `c7c12da5915f` — 12 info
  - added the optional property `errors/items/meta/limitScope` to the response with the `400` status
  - added the optional property `errors/items/meta/limitScope` to the response with the `401` status
  - added the optional property `errors/items/meta/limitScope` to the response with the `403` status
  - added the optional property `errors/items/meta/limitScope` to the response with the `404` status
  - …8 more
- **2026-08-27** `359d267dca88` — 1 info
  - deleted the `header` request parameter `X-Agent-ID` with deprecation

[Full history](https://skmtc.dev/natural/apis/natural-api/changes/ach/post.md)

---

[API](https://skmtc.dev/natural/apis/natural-api.md) · [All operations](https://skmtc.dev/natural/apis/natural-api/llms.txt) · [OpenAPI document](https://skmtc.dev/natural/apis/natural-api/revisions/acc8f2f3d25e?raw)
