Move money with transfers
Move money between your Wingspan Wallet and a linked bank account, follow the transfer until it settles, and cancel one that hasn't been submitted.
A transfer moves money between two accounts you own. One side is always an internal account, such as your Wingspan Wallet. The other side is another internal account of yours or a bank account you've linked.
A transfer into the Wallet is a Deposit. A transfer out of it is a Withdrawal.
Prerequisites
- A Wallet. See Internal accounts and balances.
- For a bank account on the other side, a linked and verified bank account. See Link and verify a bank account.
- A credential with
bookkeeping.business-banking-account:writeto create or cancel, and:readto list or retrieve. - An
Idempotency-Keyheader on every create.
Create a transfer
Call POST /v3/finance/transfers.
| Field | Required | Notes |
|---|---|---|
amount | Yes | At least 0.01 |
currency | Yes | Must match the currency of the internal account involved |
direction | Yes | Deposit or Withdrawal |
sourceAccountId | Yes | The account the money leaves |
destinationAccountId | Yes | The account the money enters |
transferMethod | No | Ach, Wire, RealTime, or Internal |
scheduledDate | No | YYYY-MM-DD |
description, metadata | No |
Wingspan works out which side is your internal account and checks that direction agrees. For a Deposit, the destination is your internal account. For a Withdrawal, the source is.
curl -X POST "https://api.wingspan.app/v3/finance/transfers" \
-H "Authorization: Bearer $WINGSPAN_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: fund-wallet-2026-10-20" \
-d '{
"amount": 2500.00,
"currency": "USD",
"direction": "Deposit",
"transferMethod": "Ach",
"sourceAccountId": "Ba7Hn2Qx5Rt8Kw3Lp6Zb9D",
"destinationAccountId": "Ia4Kq9Wn2Lx7Tz5Bm8Hc3V",
"description": "Fund Wallet"
}'// 201 Created (trimmed)
{
"id": "Tr3Wn8Qk5Lx2Bz7Mh4Rc9T",
"status": "Created",
"amount": 2500.00,
"currency": "USD",
"direction": "Deposit",
"transferMethod": "Ach",
"sourceAccountId": "Ba7Hn2Qx5Rt8Kw3Lp6Zb9D",
"destinationAccountId": "Ia4Kq9Wn2Lx7Tz5Bm8Hc3V",
"events": { "createdAt": "2026-10-20T15:02:11Z" }
}A 201 means Wingspan accepted the transfer. It doesn't mean the money has moved.
To start from the internal account instead, call POST /v3/finance/internal-accounts/{internalAccountId}/transfers. It takes amount, direction, and description, all required, plus transferMethod, counterpartyAccountId, counterpartyAccountType (InternalAccount or ExternalBankAccount), scheduledDate, and metadata. The currency is the account's own.
Follow a transfer
Read one with GET /v3/finance/transfers/{transferId}, or list them with GET /v3/finance/transfers. The list takes filter[status][eq], filter[direction][eq], sort, and page.
status | Meaning |
|---|---|
Created | Accepted, not yet sent to the payment rail |
InProgress | Sent to the payment rail |
Completed | Settled |
Failed | Didn't settle. statusReason is InternalError, ExternalFailure, BadPayoutMethod, or InsufficientFunds. |
Cancelled | Cancelled before it was sent |
Returned | The bank sent the money back |
Subscribe to webhooks instead of polling. Transfer.Created, Transfer.Updated, Transfer.Processed, Transfer.Completed, Transfer.Cancelled, and Transfer.Failed are published. See Webhooks and events.
Cancel a transfer
Call POST /v3/finance/transfers/{transferId}/cancel. It works only on a transfer Wingspan hasn't submitted to the payment rail. A transfer already submitted returns 409. On success the response is the transfer with status: Cancelled.
Permissions and step-up
If you call with a person's login session, creating and cancelling transfers return 403 with code: StepUpMfaRequired until the person completes a HighRiskWriteAction challenge. See Banking and spend.
Errors
| Status | Meaning |
|---|---|
403 | Missing scope, or StepUpMfaRequired |
404 | Neither account is an internal account you own, a bank account isn't yours, or the transfer doesn't exist. Wingspan doesn't say whether the other account exists. |
409 | IdempotencyKeyConflict (same key, different body), or the transfer can't be cancelled because it was already submitted |
422 | The amount is below 0.01, direction doesn't match the accounts, currency doesn't match the internal account, or transferMethod isn't supported |
Related pages
Updated about 1 hour ago