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

# USD payouts

> Pay out USD to US bank accounts over ACH, Wire, or FedNow, and to banks abroad over SWIFT. Covers who can receive each rail, account fields and validation, SWIFT country rules, Canadian routing, purpose codes, payment references, timing, and errors.

USD payouts go out through Lead Bank or Erebor Bank, depending on how the customer was onboarded. Pay US accounts over ACH, Wire, or FedNow, and accounts at banks outside the US over SWIFT. See [Payouts](https://dev.enterprise.moonpay.com/offramp.md) for the overall flow.

## Who can receive USD payouts

| Rail | `account_identifier` type | First party | Third party | Who can use it |
| - | - | - | - | - |
| ACH | `ACH` | Yes | Yes | Individuals and businesses |
| Wire | `Wire` | Yes | Yes | Individuals and businesses |
| FedNow | `FEDNOW` | Yes | Yes | Customers onboarded to the MoonPay USA entity. Lead Bank only |
| SWIFT | `SWIFT` | Yes | Yes | Depends on the bank's country and the customer. See [SWIFT](#swift) |

Read `abilities.fiat_payout.usd` from `GET /api/customers/{customer_id}/abilities` to see which of `ach`, `wire`, `fednow`, and `swift` (and their `_thirdparty` variants) are `Active` for a customer. RTP appears in the response but is never `Active` in production. Sandbox reports `rtp` and `rtp_thirdparty` as `Active`.

## Register the bank account

`POST /api/addresses/fiat` registers the account. Every USD rail uses the same request shape and differs only in `account_identifier`.

```bash ACH theme={null}
curl -X POST "https://api.sandbox.iron.xyz/api/addresses/fiat" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "X-API-Key: <your-api-key>" \
  -d '{
    "customer_id": "4b85d15e-f343-41c0-809c-85314cae2fa6",
    "currency": { "code": "USD" },
    "label": "Jane Doe Checking",
    "bank_details": {
      "recipient": { "type": "Individual", "given_name": "Jane", "family_name": "Doe" },
      "provider_name": "JPMorgan Chase Bank",
      "provider_country": { "code": "US" },
      "account_identifier": {
        "type": "ACH",
        "routing_number": "021000021",
        "account_number": "123456789012"
      },
      "address": {
        "street": "123 Main Street",
        "city": "New York",
        "state": "NY",
        "country": { "code": "US" },
        "postal_code": "10001"
      },
      "is_third_party": false
    }
  }'
```

> [!NOTE]
>
> `POST /api/addresses/fiat` requires an `Idempotency-Key` header. A missing key returns `400`. Only successful responses are cached, so a retry after an error runs again. See [Idempotency](https://dev.enterprise.moonpay.com/idempotency.md).

### Fields for every rail

| Field | Required | Rules |
| - | - | - |
| `customer_id` | Yes | The customer who owns the account |
| `currency` | Yes | `{ "code": "USD" }` |
| `label` | No | Your label for the account |
| `bank_details.recipient` | Yes | `Individual` with `given_name` and `family_name`, or `Business` with `name`. Each name is 1-50 characters |
| `bank_details.provider_name` | Yes | The bank's name |
| `bank_details.provider_country` | Yes | The bank's country, for example `{ "code": "US" }` |
| `bank_details.account_identifier` | Yes | The rail and account details. See below |
| `bank_details.address` | Yes | The recipient's address: `street` (2-256 characters), `city` (2-100), `state`, `country`, `postal_code` (3-20). A US `state` must be a valid state |
| `bank_details.is_third_party` | Yes | `true` when the account doesn't belong to your customer |
| `bank_details.email_address` | No | `{ "email": "..." }` |
| `bank_details.phone_number` | No | Validated and stored in E.164 format |
| `bank_details.bank_address` | No | The bank's address. Send it for SWIFT accounts |
| `bank_details.local_routing` | SWIFT in Canada | See [Canadian banks](#canadian-banks) |

### ACH and Wire

```json theme={null}
{ "type": "ACH", "routing_number": "021000021", "account_number": "123456789012" }
```

Use `"type": "Wire"` with the same two fields for a wire.

* `routing_number`: a 9-digit ABA routing number. A value that isn't exactly 9 digits fails request validation with `400` and a `"parse request payload error: ..."` body. A 9-digit number with a wrong prefix or check digit returns `400` with `"Invalid routing number"`
* `account_number`: 4-17 digits or uppercase letters

### FedNow

```json theme={null}
{ "type": "FEDNOW", "routing_number": "021000021", "account_number": "123456789012" }
```

FedNow takes the same fields as ACH. Only Lead Bank sends FedNow payouts, and only for customers onboarded to the MoonPay USA entity. The recipient's bank must accept FedNow payments.

## SWIFT

SWIFT pays USD to a bank outside the US.

```json theme={null}
{
  "type": "SWIFT",
  "bic": "BUKBGB22",
  "account_number": "GB33BUKB20201555555555"
}
```

* `bic`: uppercase letters and digits. Its country must match `provider_country`, or registration returns `400` with `"BIC country does not match provider_country"`
* `account_number`: 1-34 letters, digits, or spaces, ending in a letter or digit. Send an IBAN here for banks that use them
* `intermediary_bic`: optional. Lead Bank uses it as the correspondent bank only when it's the BIC of a US bank, and otherwise picks one itself. Erebor Bank ignores it

### Which countries

Two banks send SWIFT payouts, and each covers different countries and customers:

* **Erebor Bank** pays to 46 countries, for individuals and businesses: AE, AT, AU, BE, BH, BM, BR, BS, CA, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GR, HK, HR, HU, IE, IL, IT, KR, KY, LI, LT, LU, LV, MT, MX, NL, NO, PH, PL, PT, RO, RS, SE, SG, SI, SK, SM
* **Lead Bank** pays to every country except 28: AF, BI, BT, BY, CD, CN, CU, GW, HT, IQ, IR, KE, KP, LB, LY, MM, MZ, PK, PS, QA, RU, SD, SO, SS, SY, VE, YE, ZW. It pays businesses, and pays individuals only when MoonPay Enterprise enables it for your account

A country is open for a customer when a bank the customer is onboarded with covers it. MoonPay Enterprise checks both the bank's country (`provider_country`) and the country in the recipient's `address`. If either isn't covered, registration returns `400`:

```json 400 Bad Request theme={null}
"Bank country is not currently supported for SWIFT"
```

SWIFT payouts are USD only. Pay banks in the US over ACH, Wire, or FedNow: a SWIFT Autoramp to a US bank on Lead Bank returns `400` with `"USD SWIFT payouts to a U.S. bank are not supported; provide domestic wire (ABA) details instead"`.

### Canadian banks

A SWIFT account at a Canadian bank needs its national routing data in `bank_details.local_routing`:

```json theme={null}
"local_routing": {
  "type": "CA_ROUTING",
  "institution_number": "003",
  "transit_number": "00012"
}
```

`institution_number` is the 3-digit financial institution number and `transit_number` the 5-digit branch transit number. Without it, registration returns `400` with `"CA SWIFT accounts require local_routing of type CA_ROUTING"`. Every other country rejects `local_routing`.

### Purpose codes

Banks in the United Arab Emirates (`AE`), South Korea (`KR`), and the Philippines (`PH`) require a purpose code. Pass `swift_purpose_code` when you create the Autoramp or request the quote. A missing or unknown code returns `400`, and the message lists the codes that country accepts. Every other country rejects `swift_purpose_code`.

The purpose code is fixed when you create the Autoramp. To change it, cancel the Autoramp and create a new one. See [Edit an Autoramp](https://dev.enterprise.moonpay.com/autoramp.md#edit-an-autoramp).

## Create the payout Autoramp

Create a standing Autoramp or a quote-based Autoramp the same way as any payout. See [Payouts](https://dev.enterprise.moonpay.com/offramp.md#payout-with-an-exact-out-quote). The recipient is the registered account:

```json theme={null}
"recipient_account": {
  "type": "Fiat",
  "account_identifier": { "type": "ACH", "routing_number": "021000021", "account_number": "123456789012" }
}
```

## Payment references

Set at most one reference per Autoramp, in the field for the account's rail. A field that doesn't match the rail returns `400`, for example `"ach_payment_reference is only allowed for offramps via ACH transfer"`.

| Rail | Field | Rules |
| - | - | - |
| ACH | `ach_payment_reference` | 1-10 characters: letters, digits, spaces, and `/ - ? : ( ) . +` |
| Wire | `wire_message` | 1-140 characters, at most 4 lines of 35 characters |
| SWIFT | `swift_payment_reference` | Up to 35 characters on one line, with the same characters as ACH |
| FedNow | None | FedNow payouts don't carry a reference you set |

The ACH reference becomes the entry's statement descriptor at the recipient's bank. Lead Bank also cuts the recipient's name on an ACH entry to 22 characters and converts it to plain ASCII.

References are fixed when you create the Autoramp. On a quote-based Autoramp, the reference and `swift_purpose_code` is part of the signed quote: pass it on `GET /api/autoramps/quote`, not on `POST /api/autoramps`, which returns `400` with `"Invalid signature"` if you add it there. To use a different reference for later deposits, pass `payment_reference` on `GET /api/autoramps/{autoramp_id}/quote`. See [Quotes](https://dev.enterprise.moonpay.com/quotes.md).

## Third-party payouts

Set `is_third_party: true` when you register an account that doesn't belong to your customer, such as a supplier or a family member. ACH, Wire, FedNow, and SWIFT all pay third parties. MoonPay Enterprise screens every third-party recipient against sanctions lists when the payout runs.

## Timing

Lead Bank sends ACH payouts of up to \$1,000,000 as same-day ACH, and larger ones as next-day ACH. See [Settlement Times by Payment Method](https://dev.enterprise.moonpay.com/transaction-status.md#settlement-times-by-payment-method) for every rail.

## Fees and minimums

Banking fees per rail come from the Autoramp's fee profile. See [Fees and Invoices](https://dev.enterprise.moonpay.com/fees-and-invoices.md). A SWIFT payout under 5 USD, or any other payout under 1 USD, ends as `RejectedMinAmount`. See [Minimum Transaction Amount](https://dev.enterprise.moonpay.com/limits-and-minimum.md#minimum-transaction-amount).

## What can go wrong

| Response | Cause |
| - | - |
| `400` `"parse request payload error: ..."` | The routing number isn't exactly 9 digits |
| `400` `"Invalid routing number"` | The routing number's prefix or check digit is wrong |
| `400` `"BIC country does not match provider_country"` | The BIC belongs to a different country than `provider_country` |
| `400` `"Bank country is not currently supported for SWIFT"` | Neither bank the customer can use covers the bank's country or the recipient's country |
| `400` `"CA SWIFT accounts require local_routing of type CA_ROUTING"` | A Canadian SWIFT account without `local_routing` |
| `409` `"A fiat address with this bank account already exists for this customer"` | The account is already registered. Reuse its ID |
| `422` `{ "message": "Customer does not have access to this rail", "trace_id": "..." }` | The customer can't use any provider for this rail yet. Check `abilities.fiat_payout.usd` |

## Sandbox

Sandbox registers USD accounts automatically, so a new account reaches `Registered` without a manual step. Test the full payout with [Test the full flow in Sandbox](https://dev.enterprise.moonpay.com/offramp.md#test-the-full-flow-in-sandbox).
