Send funds tutorial
Use this for contractor and gig-worker payouts, marketplace disbursements, payouts within a transfer group, or moving your own funds to your bank account.
Before you start
- The source (sender) account has the
send-fundscapability for the rail you'll use, pluswallet.balance. The recipient only needstransfers. - The recipient has a linked bank account or eligible card, or you'll use a payment link so they can add one
- The source wallet is funded to cover the payout and any payout fee
Compare rails by speed and reversibility in choose a payment method. Prefer instant-bank-credit over rtp-credit, which will be deprecated.
Send funds to a recipient
The following steps walk you through finding an account and its available payment methods, and creating a payout.
Get accountID
Retrieve the accountID for the Moov account you want to use as a source. Repeat the step for the destination account. You'll use the accountID to retrieve the payment methods in the next step.
Get payment methods
Get the paymentMethodID for both the source and destination accounts.
Create a payment link or transfer
To send a payout, create a payment link or transfer from a sender (source) to a recipient (destination). To have the recipient pay the payout fee instead of the funding wallet (the default), set feePaidBy as described in payout fees.
Payment link
curl -X POST "https://api.moov.io/accounts/{accountID}/payment-links" \
-H "Authorization: Bearer {token}" \
-H "x-moov-version: v2026.07.00" \
--data-raw '{
"accountID": "c197cd40-7745-4413-8f3b-ec962d1b5225",
"merchantPaymentMethodID": "3afc7533-7095-43bb-b21a-5c4dc5568451",
"partnerAccountID": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"amount": {
"currency": "USD",
"value": 10000
},
"maxUses": 0,
"expiresOn": "2026-08-24T14:15:22Z",
"display": {
"title": "string",
"description": "Payment for service",
"callToAction": "confirm"
},
"payout": {
"allowedMethods": [
"push-to-card",
"ach-credit-same-day"
],
"recipient": {
"phone": {
"number": "5555555555",
"countryCode": "1"
}
},
"pushOptions": {
"allowedSpeeds": ["instant", "deferred"],
"deferredBy": "24h"
},
"feePaidBy": {
"instant-push-to-card": "destination",
"deferred-push-to-card": "destination",
"ach-credit-same-day": "source"
}
}
}'
mc, _ := moov.NewClient()
var accountID string
mc.CreateTransfer(ctx, accountID, moov.CreateTransfer{
Source: moov.CreateTransfer_Source{
PaymentMethodID: "string",
},
Destination: moov.CreateTransfer_Destination{
PaymentMethodID: "string",
},
Amount: moov.Amount{
Value: 315, // $3.15
Currency: "USD",
},
Description: "Optional description of transaction",
})
Transfer
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers" \
-H "Authorization: Bearer {token}" \
-H "x-idempotency-key: UUID" \
-H "X-Wait-For: rail-response" \
-H "x-moov-version: v2026.07.00" \
--data-raw '{
"source": {
"paymentMethodID": "string"
},
"destination": {
"paymentMethodID": "string"
},
"amount": {
"value": 10000,
"currency": "USD"
},
"feePaidBy": {
"payout": "destination"
},
"description": "General contractor service"
}'
mc, _ := moov.NewClient()
var accountID string
mc.CreateTransfer(ctx, accountID, moov.CreateTransfer{
Source: moov.CreateTransfer_Source{
PaymentMethodID: "string",
},
Destination: moov.CreateTransfer_Destination{
PaymentMethodID: "string",
},
Amount: moov.Amount{
Value: 315, // $3.15
Currency: "USD",
},
Description: "Optional description of transaction",
})
Line items
Line items allow you to list items within the transaction, each with their own distinct name, description, image, options, and price modifier. For tracking purposes, you can give each item a unique identifier using the productID field.
The total amount of the transfer must account for any and all costs associated with a line item's base price and price modifiers as well as sales tax:
amount = lineItems + salesTaxAmount
The shape of line items is the same for payment links and transfers, and can be added to both requests.
{
"lineItems": {
"item": {
"basePrice": {
"currency": "USD",
"valueDecimal": "100.00"
},
"name": "General contractor service",
"productID": "5afv22245-7095-24ba-b21a-5c4dc993737",
"quantity": 1
}
}
}
Send funds using a transfer group
When creating a transfer, you also have the option to use transfers groups. To create a transfer group, provide the transferID (of the immediate preceding transfer) as the source. Transfers that belong to a group must have an amount less than or equal to the amount of the source transfer. See the transfer groups guide for more detailed information.
1{
2 "source": {
3 "transferID": "transferID"
4 },
5 "destination": {
6 "paymentMethodID": "string"
7 },
8 "amount": {
9 "value": 315,
10 "currency": "USD"
11 },
12 "description": "Optional description of transaction"
13}
Amounts are in cents, so a value of 315 is $3.15.
Track the transfer
Subscribe to the transfer.updated webhook event. It fires on every transfer status change and on rail-specific updates. The payout succeeded when the transfer status is completed; check failureReason if it's failed.
Rail-specific statuses are on the destination: achDetails (ACH statuses), instantBankDetails (instant payment statuses), or cardDetails (push to card statuses).
To stop an ACH payout, cancel it before the credit originates. Instant payments are final once sent.
Send funds to yourself
Self-to-self transfers move funds between your own wallet and bank accounts, for example:
- A company transferring funds between accounts at two separate banks
- A contractor moving money from their Moov wallet to their bank account
- A platform adding funds from their bank account to their Moov wallet
The steps below move funds from your wallet to your bank account. They assume you have API keys; see the quick start if not.
Set up the account
Start by creating your Moov account. Request at least one send-funds capability for the account. You will need to submit specific data about the user to Moov for verification before the capability is enabled. See our capabilities guide for a list of required information.
curl -X POST "https://api.moov.io/accounts" \
-H "Authorization: Bearer {token}" \
-H "x-moov-version: v2026.07.00" \
--data-raw '{
"accountType": "individual",
"profile": {
"individual": {
"email": "julesjacksonyoga@moov.io",
"name": {
"firstName": "Jules",
"lastName": "Jackson"
}
}
},
"capabilities": ["send-funds"],
"foreignID": "unique-correlation-id"
}'
mc, _ := moov.NewClient()
mc.CreateAccount(ctx, moov.CreateAccount{
Type: moov.AccountType_Business,
Profile: moov.CreateProfile{
Business: &moov.CreateBusinessProfile{
Name: "Whole Body Fitness LLC",
Type: moov.BusinessType_Llc,
},
},
RequestedCapabilities: []moov.CapabilityName{
moov.CapabilityName_SendFundsACH,
},
ForeignID: "unique-correlation-id",
})
Add bank account
Link your bank account to your Moov account.
curl -X POST "https://api.moov.io/accounts/{accountID}/bank-accounts" \
-H "Authorization: Bearer {token}" \
-H "x-moov-version: v2026.07.00" \
--data-raw '{
"account": {
"accountNumber": "0004321567000",
"bankAccountType": "checking",
"holderName": "Jules Jackson",
"holderType": "individual",
"routingNumber": "123456789"
}
}'
mc, _ := moov.NewClient()
var accountID string
mc.CreateBankAccount(ctx, accountID, moov.WithBankAccount(moov.BankAccountRequest{
AccountNumber: "0004321567000",
AccountType: moov.BankAccountType_Checking,
HolderName: "Jules Jackson",
HolderType: moov.HolderType_Individual,
RoutingNumber: "123456789",
}), moov.WaitForPaymentMethod())
Get payment methods
Get the available payment methods from the generate transfer options POST endpoint. Specify your account ID as both the source and the destination. You will get a list that includes all the payment methods you can use to make a self-to-self transfer. The payment method for the source of the transfer will be moov-wallet, while the payment method for the destination will be ach-credit-standard or ach-credit-same-day.
curl -X POST "https://api.moov.io/accounts/{accountID}/transfer-options" \
-H "Authorization: Bearer {token}" \
-H "x-moov-version: v2026.07.00" \
--data-raw '{
"amount": {
"value": 100,
"currency": "USD"
},
"destination": {
"accountID": "string"
},
"source": {
"accountID": "string"
}
}'
mc, _ := moov.NewClient()
// your partner accountID
var accountID string
mc.TransferOptions(ctx, accountID, moov.CreateTransferOptions{
Source: moov.CreateTransferOptionsTarget{
AccountID: "string",
},
Destination: moov.CreateTransferOptionsTarget{
AccountID: "string",
},
Amount: moov.Amount{
Currency: "USD",
Value: 1,
},
})
Initiate the transfer
Create a transfer from your wallet to your bank account with the payment method IDs from the transfer options response. Track it the same way as a payout to a recipient.
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers" \
-H "Authorization: Bearer {token}" \
-H "x-idempotency-key: UUID" \
-H "X-Wait-For: rail-response" \
-H "x-moov-version: v2026.07.00" \
--data-raw '{
"amount": {
"value": 100,
"currency": "USD"
},
"destination": {
"paymentMethodID": "string"
},
"source": {
"paymentMethodID": "string"
},
"description": "Optional transaction description."
}'
mc, _ := moov.NewClient()
var accountID string // Partner account
mc.CreateTransfer(ctx, accountID, moov.CreateTransfer{
Amount: moov.Amount{
Currency: "USD",
Value: 100, // $1.00
},
Destination: moov.CreateTransfer_Destination{
PaymentMethodID: "string",
},
Source: moov.CreateTransfer_Source{
PaymentMethodID: "string",
},
Description: "Optional transaction description.",
})
Next steps
- Payout fees: pass the fee to the recipient
- Payment links: let recipients choose their payout method
- Sweeps: pay out a wallet balance automatically every day