A transfer is any movement of funds. Banking supports four transfer types: ACH, Wire (Fedwire), RTP (Real-Time Payments), and internal book transfers between accounts on the platform. Each has different settlement, cost, and operational characteristics. The same controller serves all four.
Transfer types at a glance
| Type | Settlement | Fee | Hours | Max amount |
|---|---|---|---|---|
| ACH (standard) | 2 business days | $0.25 | Batch (multiple windows/day) | Sponsor-defined |
| ACH (same-day) | Same day | $0.25 | Cutoff windows | Lower limits per NACHA |
| Wire | Same day | $30 ($25 transfer + $5 processing) | Mon-Fri, 9 PM ET (prev) – 7 PM ET | Sponsor-defined |
| RTP | Seconds | $0.50 | 24/7/365 | $1,000,000 per transaction |
| Internal | Immediate | Free | 24/7 | Limited by daily transfer cap |
Fees and cutoffs are sponsor-bank dependent — defaults shown above. Confirm against your provider's contract.
Generic transfer endpoint
/banking/transfersJWTThe generic endpoint dispatches to the right rail based on transferType.
| Field | Type | Description |
|---|---|---|
| transferType* | 'ach' | 'wire' | 'rtp' | 'internal' | The rail to use. |
| direction* | 'inbound' | 'outbound' | 'internal' | Outbound (sending money out), inbound (pulling money in via ACH debit), or internal (between two platform accounts). |
| sourceAccountId | string | The platform-side account, required for outbound and internal. |
| destinationAccountId | string | The platform-side destination, required for internal and inbound. |
| destinationRoutingNumber | string | External destination routing — required for outbound ACH/Wire/RTP. |
| destinationAccountNumber | string | External destination account number. |
| destinationAccountName | string | Beneficiary name on the destination account. |
| destinationBankName | string | Required for wires. |
| amount* | number | Transfer amount in the account currency. |
| currency | string | Defaults to |
| description | string | Statement memo / description. |
| memo | string | Internal memo, not transmitted on the rail. |
| achClass | 'PPD' | 'CCD' | 'WEB' | ACH SEC code. PPD = consumer, CCD = business, WEB = internet-authorised. |
| idempotencyKey | string | Pass a stable key to dedupe retries. |
ACH
ACH (Automated Clearing House) is the workhorse — batch-settled, low-cost, slow. The Federal Reserve and EPN run the rails; sponsor banks submit batches multiple times per day.
/banking/transfers/achJWT{
"direction": "outbound",
"sourceAccountId": "acc_abc",
"destinationRoutingNumber": "021000021",
"destinationAccountNumber": "9876543210",
"destinationAccountName": "Alice Doe",
"amount": 1000.00,
"description": "March payout",
"achClass": "PPD"
}
SEC codes
| Code | Use |
|---|---|
PPD | Personal — consumer-authorised, recurring or one-time. |
CCD | Corporate — business-to-business. |
WEB | Internet-authorised debit (consumer giving permission online). |
Pick the right code for your authorisation type. The wrong code can cause returns even if account details are correct.
Same-day vs next-day
Same-day ACH is supported. There is no separate /transfers/ach/same-day endpoint — same-day eligibility depends on the time you submit relative to the day's cutoff windows (typically 10:30 AM, 2:45 PM, and 4:45 PM ET). Submissions after the last window roll to the next business day.
Return codes
Returns surface on the transfer record's failureReason. Common codes:
| Code | Reason |
|---|---|
R01 | Insufficient funds |
R02 | Account closed |
R03 | No account / unable to locate |
R04 | Invalid account number |
R05 | Unauthorized debit |
R06 | Returned per ODFI request |
R07 | Authorization revoked |
R08 | Payment stopped |
R09 | Uncollected funds |
R10 | Customer advises not authorized |
Returns can arrive up to 60 days after settlement (R10 in particular). Reconciliation needs to handle the long tail.
Wire
Wires settle the same day with no return window — once it's gone, it's gone.
/banking/transfers/wireJWT{
"direction": "outbound",
"sourceAccountId": "acc_abc",
"destinationRoutingNumber": "021000089",
"destinationAccountNumber": "9876543210",
"destinationAccountName": "Acme Vendors LLC",
"destinationBankName": "Wells Fargo",
"amount": 50000.00,
"description": "Invoice 2026-0142"
}
Wires require destinationBankName. The response carries an imad (Input Message Accountability Data) reference — this is the wire's unique identifier on Fedwire and the only useful trace for missing wires.
Once a wire has cleared, it cannot be reversed by the sender. Recall requests are best-effort and depend on the receiving bank's cooperation. Always verify destination details before submitting, and use larger-amount confirmation flows.
RTP
Real-Time Payments clear in seconds, run 24/7, and have a $1M per-transaction ceiling. Use the generic endpoint with transferType: "rtp":
{
"transferType": "rtp",
"direction": "outbound",
"sourceAccountId": "acc_abc",
"destinationRoutingNumber": "021000021",
"destinationAccountNumber": "9876543210",
"destinationAccountName": "Alice Doe",
"amount": 250.00
}
Not all destination banks accept RTP — eligibility depends on the receiving bank being on The Clearing House network. If the destination doesn't support RTP, the platform will fail the transfer and you can retry on ACH.
RTP also supports Request for Payment (RfP), where you ask the customer to push funds to you instead of pulling. RfP is supported via the same controller through metadata flags; check with your sponsor for availability.
Internal (book transfers)
Movement between two accounts on the platform — no rail involved, no fee, immediate.
{
"transferType": "internal",
"direction": "internal",
"sourceAccountId": "acc_abc",
"destinationAccountId": "acc_def",
"amount": 500.00,
"description": "Sweep to savings"
}
The platform debits source, credits destination, and posts a single balanced journal entry to the ledger. This is the only transfer type that can complete inside a single transaction.
Lifecycle
pending → processing → completed
↓
failed
pending covers the window between submission and rail acceptance. processing means the rail has accepted but settlement hasn't confirmed. completed is final. failed releases any held funds back to available.
Cancel
/banking/transfers/{id}/cancelJWTBody: { reason: string }. Cancels a pending transfer before submission. Once processing, you cannot cancel — only wait for the rail's outcome.
Reads
/banking/transfersJWTFilter with accountId, status, transferType, page, pageSize.
/banking/transfers/{id}JWTSingle transfer with full status detail and rail-specific metadata (IMAD for wires, trace number for ACH).
Fund holds
When you initiate an outbound transfer, the platform places a hold for the amount + fee on the source account immediately. The available balance drops, the pending balance rises. On settlement, the hold is released and the balance is debited; on failure, the hold is released and the balance is restored.
This is why available != current matters — available already accounts for in-flight outbound transfers.
Idempotency
Pass idempotencyKey in any transfer body. Same key + same body = same transfer ID. Same key + different body = error. Use a stable key tied to your business event (e.g., payout-2026-04-1234) on retry-prone code paths.