# Pay out to a bank account

> Create an individual account, link and verify a bank account, pick a payment method, pay out with ACH or instant payments, and handle returns.

> AI agents: search and read all Moov docs with the docs MCP server at https://docs.moov.io/mcp (no API key). Setup: https://docs.moov.io/guides/developer-tools/mcp-ai/docs-mcp/index.md

Pay a person from your Moov wallet to their bank account, by ACH or instant payments (RTP or FedNow), and handle the payout if it comes back.

In this recipe, your partner account pays a recipient, such as a contractor, seller, or claimant. Your Moov wallet is the source, the recipient's bank account is the destination, and the recipient only needs the `transfers` capability. You'll create the recipient, link and verify their bank account, choose a rail, send the payout, and react to the webhooks that tell you whether it arrived.

## Prerequisites

- Everything in [Before you start](/guides/get-started/recipes/index.md#before-you-start): test mode API keys, authentication headers, your partner account ID, and a webhook endpoint
- On your partner account: `wallet.balance` plus `send-funds.ach` for ACH payouts, or `send-funds.instant-bank` for instant payouts. Check them with the list capabilities [endpoint](/api/moov-accounts/capabilities/list/index.md).
- A wallet balance that covers the payout. To add funds, follow [fund and spend from a wallet](/guides/get-started/recipes/wallet-funding/index.md); in test mode, weekday ACH debits complete in about an hour.

## Steps

### Create the recipient's account

Create an individual account for the recipient with the create account [endpoint](/api/moov-accounts/accounts/create/index.md). A payout recipient only needs `transfers`, which Moov enables automatically, so you don't need to request capabilities or collect identity documents for this account.

```zsh
curl -X POST "https://api.moov.io/accounts" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00" \
  -d '{
    "accountType": "individual",
    "profile": {
      "individual": {
        "name": { "firstName": "Jules", "lastName": "Jackson" },
        "email": "julesjacksonyoga@moov.io"
      }
    },
    "foreignID": "contractor-1042"
  }'
```

Save the `accountID`. Deeper guide: [create an individual account](/guides/accounts/create-accounts/individual/index.md).

### Link the recipient's bank account

Link the bank account with the link bank account [endpoint](/api/sources/bank-accounts/create/index.md). In test mode, use routing number `021000021` to get an account that's eligible for instant payments, or `322271627` for an ACH-only account. Any account number works.

```zsh
curl -X POST "https://api.moov.io/accounts/{recipientAccountID}/bank-accounts" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00" \
  -H "X-Wait-For: payment-method" \
  -d '{
    "account": {
      "holderName": "Jules Jackson",
      "holderType": "individual",
      "accountNumber": "12345654321",
      "bankAccountType": "checking",
      "routingNumber": "021000021"
    }
  }'
```

Save the `bankAccountID`. With `X-Wait-For: payment-method`, the response lists the new payment methods. You can also link through [Plaid or MX](/guides/sources/bank-accounts/link-bank-accounts/index.md), or let the recipient add the account themselves with the [payment methods Drop](/moovjs/drops/payment-methods/index.md). Deeper guide: [link bank accounts](/guides/sources/bank-accounts/link-bank-accounts/index.md).

### Verify the bank account

Credits to a bank account (`ach-credit-standard`, `ach-credit-same-day`, `instant-bank-credit`) are available as soon as the account is linked. Verification is still a best practice for payouts, because it confirms the recipient owns the account before you send money, and it's required if you'll ever debit the account.

Start instant micro-deposit verification with the initiate verification [endpoint](/api/sources/bank-accounts/initiate-bank-account-verification/index.md). Moov sends $0.01 with a 4-digit code, over RTP when the bank supports it and same-day ACH otherwise.

```zsh
curl -X POST "https://api.moov.io/accounts/{recipientAccountID}/bank-accounts/{bankAccountID}/verify" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00" \
  -H "X-Wait-For: rail-response"
```

The recipient finds the code in their bank transactions and enters it in your app. Submit it with the complete verification [endpoint](/api/sources/bank-accounts/complete-bank-account-verification/index.md) (`PUT` on the same path, body `{"code": "MV1234"}`). In test mode, the code is `0001`. The bank account's `status` changes to `verified`. Deeper guide: [bank account verification](/guides/sources/bank-accounts/verification/index.md).

### Choose the payment methods

You need two payment method IDs: the `moov-wallet` payment method on your partner account (the source) and a bank credit payment method on the recipient's account (the destination). List the recipient's payment methods for this bank account with the list payment methods [endpoint](/api/sources/payment-methods/list/index.md):

```zsh
curl -X GET "https://api.moov.io/accounts/{recipientAccountID}/payment-methods?sourceID={bankAccountID}" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00"
```

Pick the destination by speed:

| Payment method        | Arrives                                     | Notes                                                                                              |
|-----------------------|---------------------------------------------|----------------------------------------------------------------------------------------------------|
| `instant-bank-credit` | Seconds, 24/7/365                           | Instant payments (RTP or FedNow). Only present if the receiving bank is eligible. Final once sent. |
| `ach-credit-same-day` | Same business day if sent before the cutoff | Up to $500,000 per transfer                                                                        |
| `ach-credit-standard` | 1-2 business days                           | Lowest cost                                                                                        |

Then get your own `moov-wallet` payment method with the same endpoint on your partner account and `paymentMethodType=moov-wallet`. To ask Moov which combinations are valid for a specific amount, use the transfer options [endpoint](/api/money-movement/transfers/options/index.md). Deeper guides: [payment methods](/guides/money-movement/payment-methods/index.md) and [ACH processing speeds](/guides/money-movement/ach/ach-processing-speeds/index.md).

### Send the payout

Create the transfer with the create transfer [endpoint](/api/money-movement/transfers/create/index.md). This example sends an instant payment; for ACH, swap in the `ach-credit-same-day` or `ach-credit-standard` payment method ID. Nothing else in the request changes.

```zsh
curl -X POST "https://api.moov.io/accounts/{partnerAccountID}/transfers" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00" \
  -H "X-Idempotency-Key: 0f8e2c6a-7d41-4b9e-a3c5-6e1f2d3c4b5a" \
  -H "X-Wait-For: rail-response" \
  -d '{
    "source": { "paymentMethodID": "{partnerWalletPaymentMethodID}" },
    "destination": { "paymentMethodID": "{recipientInstantBankPaymentMethodID}" },
    "amount": { "currency": "USD", "value": 25000 },
    "description": "Invoice 1042 payout"
  }'
```

For instant payments, the response includes `destination.instantBankDetails` with the `network` used (`rtp` or `fednow`) and a rail `status`. For ACH, it includes `destination.achDetails` with a `traceNumber` the recipient can give their bank. To pass the payout fee to the recipient, see [payout fees](/guides/send-payments/payout-fees/index.md). Deeper guides: [send funds](/guides/send-payments/send-funds/index.md) and [instant payments](/guides/send-payments/instant-payments/index.md).

### Handle failures and returns

Subscribe to `transfer.updated` and `bankAccount.updated`, then look up the transfer when either fires:

```zsh
curl -X GET "https://api.moov.io/accounts/{partnerAccountID}/transfers/{transferID}" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00"
```

What happens depends on the rail:

- **Instant payments:** the receiving bank answers in seconds. A rejection sets `instantBankDetails.status` to `failed` with a `failureCode` such as `account-closed`, and the money stays in your wallet. Instant payments that complete can't be returned.
- **ACH credits:** the receiving bank can return the credit after it's sent, typically within two banking days. A return sets `destination.achDetails.status` to `returned`, fills in `destination.achDetails.return.code` (for example `R03`, no account), changes the transfer `status` to `reversed`, and credits the amount back to your wallet.

Either way, check the bank account's `status`. If it's `errored`, the account can't be used again; ask the recipient to link a new one. If it's `verificationFailed`, re-verify it. To test returns, send an ACH credit for `5503` ($55.03, `R03`) or an instant payment for `7204` ($72.04, account closed). Deeper guides: [ACH returns](/guides/money-movement/ach/returns/index.md) and [bank account status](/guides/sources/bank-accounts/bank-account-status/index.md).

## What to watch for

| Signal                                         | What it means                                                                                                     | What to do                                                                                           |
|------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| `bankAccount.updated` with `status` `verified` | The recipient confirmed ownership                                                                                 | Allow payouts to this account                                                                        |
| `transfer.updated` with `status` `completed`   | Funds were delivered (instant) or the ACH credit settled                                                          | Mark the payout as paid                                                                              |
| `transfer.updated` with `status` `failed`      | The payout was rejected before funds moved, or your wallet didn't have enough funds (`wallet-insufficient-funds`) | Check `failureReason`; fund your wallet or fix the bank account and retry with a new idempotency key |
| `transfer.updated` with `status` `reversed`    | An ACH credit was returned after it was sent                                                                      | Read the return code; funds are back in your wallet                                                  |
| `bankAccount.updated` with `status` `errored`  | The bank account can't receive payments                                                                           | Ask the recipient to link a new bank account                                                         |

## Next steps

- [Push to card](/guides/send-payments/push-to-card/index.md): Pay out instantly to a debit card instead of a bank account.
- [Scheduled payouts](/guides/money-movement/scheduling/index.md): Send recurring or future-dated payouts.
- [Fund your wallet](/guides/get-started/recipes/wallet-funding/index.md): Keep a balance ready for payouts with ACH debits and sweeps.
- [Webhook events](/guides/webhooks/webhook-events/index.md): See every event payload Moov sends.

