---
title: "Send a same-day US domestic wire"
description: "Save a US account as a wire payee with its wire routing number and send a same-day Fedwire payment with a 35-character message."
---
Use this recipe to save a US account as a wire payee with its wire routing number and send a same-day Fedwire payment with a message of up to 35 characters.

**Who it is for.** A US property manager wiring a 48,000 USD closing payment to a title company's escrow account.

**Status.** Available from bank-held and wallet-backed USD accounts.

## Money example

1. The customer's USD account holds 60,000.00 USD.
2. The customer wires 48,000.00 USD to Lakeside Title LLC. In this example, the fee on your plan is 15.00 USD.
3. Gravv debits the account 48,015.00 USD. Lakeside receives 48,000.00 USD the same day.

## Before you start

- Everything in [Pay a US bank account by ACH](/recipes/bank-payouts/pay-a-us-bank-account-by-ach#before-you-start).
- The receiving bank's **wire** routing number. Some banks use a different ABA number for wires than for ACH.

## Find out what is required

The payee has the same fields as for ACH, with `"payment_rail": "wire"`. When you save the payee, Gravv checks the routing number against the wire directory. If the routing number cannot receive wires, the response says so.

## Steps

### 1. Save the wire payee

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v1/external-accounts \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: bfd14696-c472-43f8-88ce-960042cf9499' \
     --data '
{
  "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "payee_type": "ach_wire",
  "currency": "USD",
  "account_name": "Lakeside Title LLC",
  "account_number": "4400918273",
  "routing_number": "021000021",
  "payment_rail": "wire",
  "account_owner_type": "business",
  "bank_name": "JPMorgan Chase Bank",
  "internal_account_id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
  "address": {
    "address_line1": "200 Park Avenue",
    "city": "New York",
    "state": "NY",
    "postal_code": "10166",
    "country": "US"
  }
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/external-accounts", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "bfd14696-c472-43f8-88ce-960042cf9499",
  },
  body: JSON.stringify({
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "payee_type": "ach_wire",
    "currency": "USD",
    "account_name": "Lakeside Title LLC",
    "account_number": "4400918273",
    "routing_number": "021000021",
    "payment_rail": "wire",
    "account_owner_type": "business",
    "bank_name": "JPMorgan Chase Bank",
    "internal_account_id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
    "address": {
      "address_line1": "200 Park Avenue",
      "city": "New York",
      "state": "NY",
      "postal_code": "10166",
      "country": "US"
    }
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v1/external-accounts",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "bfd14696-c472-43f8-88ce-960042cf9499",
    },
    json={
        "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "payee_type": "ach_wire",
        "currency": "USD",
        "account_name": "Lakeside Title LLC",
        "account_number": "4400918273",
        "routing_number": "021000021",
        "payment_rail": "wire",
        "account_owner_type": "business",
        "bank_name": "JPMorgan Chase Bank",
        "internal_account_id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
        "address": {
            "address_line1": "200 Park Avenue",
            "city": "New York",
            "state": "NY",
            "postal_code": "10166",
            "country": "US",
        },
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

```json title="Response"
{
  "data": {
    "account_name": "LAKESIDE TITLE LLC",
    "account_number": "4400918273",
    "account_owner_type": "business",
    "address": {
      "address_line1": "200 Park Avenue",
      "city": "New York",
      "country": "US",
      "postal_code": "10166",
      "state": "NY"
    },
    "currency": "USD",
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "date_created": "2026-10-13T22:40:02.118230Z",
    "id": "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b",
    "institution_name": "JPMorgan Chase Bank",
    "payee_type": "ach_wire",
    "routing_number": "021000021",
    "status": "pending"
  },
  "error": null
}
```

### 2. Wait until the payee is active

Listen for `external_account.active`, or poll [`GET /v1/external-accounts/6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b`](/api-reference/external-accounts/get-v1-external-accounts-external-account-id).

### 3. Send the wire

`payment_rail_reference` is the note for the receiving bank. It can be up to 35 characters of letters, digits, spaces and `/ - ? : ( ) . , ' +`. On payouts from wallet-backed accounts, Gravv passes the note to the bank.

On payouts from a bank-held account, like the one here, Gravv checks the note but does not send it. Gravv sends `description` to the bank as the purpose of payment instead, so write what the money is for.

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: 1bef266a-7450-4dd7-90fe-b6cad155a5b4' \
     --data '
{
  "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "source": {
    "source_type": "internal_account",
    "id": "c56a4180-65aa-42ec-a945-5fd21dec0538"
  },
  "destination": {
    "destination_type": "external_account",
    "id": "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b",
    "rail": "wire"
  },
  "amount": "48000.00",
  "description": "Closing funds 12 Elm St escrow 5521",
  "client_reference": "closing-5521",
  "payment_rail_reference": "Escrow 5521 / 12 Elm St"
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/transfer", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "1bef266a-7450-4dd7-90fe-b6cad155a5b4",
  },
  body: JSON.stringify({
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "source": {
      "source_type": "internal_account",
      "id": "c56a4180-65aa-42ec-a945-5fd21dec0538"
    },
    "destination": {
      "destination_type": "external_account",
      "id": "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b",
      "rail": "wire"
    },
    "amount": "48000.00",
    "description": "Closing funds 12 Elm St escrow 5521",
    "client_reference": "closing-5521",
    "payment_rail_reference": "Escrow 5521 / 12 Elm St"
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v1/transfer",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "1bef266a-7450-4dd7-90fe-b6cad155a5b4",
    },
    json={
        "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "source": {
            "source_type": "internal_account",
            "id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
        },
        "destination": {
            "destination_type": "external_account",
            "id": "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b",
            "rail": "wire",
        },
        "amount": "48000.00",
        "description": "Closing funds 12 Elm St escrow 5521",
        "client_reference": "closing-5521",
        "payment_rail_reference": "Escrow 5521 / 12 Elm St",
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

```json title="Response"
{
  "data": {
    "amount": "48000",
    "amount_currency": "USD",
    "reference": "5a9c3e1f-7b2d-4f6a-8c0e-2d4f6a8b0c12",
    "date_created": "2026-10-13T14:30:05.204Z",
    "transfer_status": "pending",
    "transaction_id": "7e1a3c5b-9d2f-4a6c-8e0b-3f5a7c9e1b23",
    "local_amount": null,
    "local_currency": null,
    "fee": "15",
    "fee_currency": "USD",
    "requires_approval": false
  },
  "error": null
}
```

### 4. Follow it to the end

Read [`GET /v1/transactions/7e1a3c5b-9d2f-4a6c-8e0b-3f5a7c9e1b23`](/api-reference/transactions/get-v1-transactions-transaction-id) (it shows `transaction_type` `bank_account` and `channel` `wire`), or wait for `transfer.status.completed`.

## What can go wrong

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `routing number <routing_number> cannot receive wires; use the bank's wire routing number: invalid input` | The wire payee has an ACH-only routing number | Ask the payee for the wire routing number, or save the payee for ACH. Use a new `Idempotency-Key` |
| 400 `payment_rail_reference for wire must be at most 35 characters: letters, digits, spaces and / - ? : ( ) . , ' +` | The message is too long, or has characters such as `#`, `&` or `_` | Shorten it. Write `No` instead of `#` |
| 400 `this payee is registered for ach transfers, not wire — initiate on rail "ach", or add a payee on the wire rail` | You saved the payee for ACH | Save a wire payee for the same account. See [two rails](/recipes/bank-payouts/save-one-account-for-two-rails) |
| 400 `insufficient balance` | The amount plus the fee is more than the balance | Fund the account first |
| Webhook `transfer.status.failed` with `event_data.transfer_status` `manual_processing_required`, transaction still `pending` | The bank's response was unclear, so a person checks it before Gravv retries anything. This prevents a double payment | Do not send it again. Wait for the next webhook, or contact support with the `reference` |
| Every payee and transfer error in [the ACH recipe](/recipes/bank-payouts/pay-a-us-bank-account-by-ach#what-can-go-wrong) also applies to wires | | |

## Webhooks you will receive

You receive `external_account.created`, then `external_account.active`, then several `transfer.status.pending` events, then `transfer.status.completed`. See [Transfer events](/platform/webhooks/event-catalogue#transfers).

## Testing in sandbox

Test as for ACH. Fund the account with [`POST /v2/accounts/simulate/deposit`](/api-reference/accounts-v2/post-v2-accounts-simulate-deposit) and `"rail": "wire"`. The routing number `021000021` passes the wire directory check in sandbox, and the payee becomes `active` in a few seconds.

## Reference

- [Add an external account](/api-reference/external-accounts/post-v1-external-accounts)
- [Create a transfer](/api-reference/transfer/post-v1-transfer)
- [Get a transaction](/api-reference/transactions/get-v1-transactions-transaction-id)
