Overview
Initiate a payout from an end-user’s SPEND wallet to a linked payout method (bank account or card). The wallet is inferred from the linked account; the caller does not pass a wallet ID. Auth: Bearer token with scopeexternal.apis (authorizer: walletos-account-service-{stage}-authorizer).
Rate limit: 1 withdrawal per minute per user (and IP). Returns 429 if exceeded.
How it works
- Auth – Request must include a valid Bearer token;
claims.subis the entity (user/business) making the withdrawal. - Linked account –
linkedAccountIdmust exist and its wallet must be associated with that entity. - Validation – Body is validated (amount, currency, walletType, reason; MFA is not required for this external endpoint).
- Balance – Wallet balance must be at least
amount + fees. - Payout – Debit wallet, create transaction, and process payout. If the linked account is a bank and
routingTypeis RTP, real-time payment (RTP) is used; otherwise ACH is used. For card linked accounts, push-to-card is used regardless ofroutingType.
Endpoint
- POST
{{LIQUIDITY_URL}}/v1/ext/linked-accounts/:currency/:linkedAccountId/withdrawal - Auth: Bearer
{{accessToken}}(scopeexternal.apis)
Path Parameters
Headers
Request Body
Note: MFA is not required for this external payout endpoint. Do not send
mfaCode.
Request Examples
RTP bank payout
ACH bank payout
Card payout (routingType optional)
Supported Payout Types
Allowed
routingType values: ACH, RTP, WIRE, BANK only. Any other value returns a validation error.
Response
Success (200)
- Queued means the withdrawal was accepted and processing started. Final status may be delivered via webhooks or a separate status API.
data.amountis the total debited from the wallet (payout amount + fees).
Response Fields
Error (4xx / 5xx)
Typical Error Cases
Validation Rules (Summary)
- amount – Required, number, > 0.
- walletType – Required, must be
"SPEND". - reason – Required, string.
- routingType – Optional. If present, must be one of:
ACH,RTP,WIRE,BANK. - currency – From path; must be
USD(only supported currency). - linkedAccountId – From path; must be a valid UUID of an existing linked account whose wallet is associated with the authenticated entity. See Link Bank Account, Link Card Account, or Link International Bank Account for how to link an account.
- MFA – Not required for this external endpoint. Do not send
mfaCode.
Payment-Link / Merchant-Funded Withdrawals
If the request is made in the context of a payment link (application token) withwithdrawalSource === 'MERCHANT_WALLET':
- amount in the body must equal the amount on the application token; otherwise the response is 400
"Malformed request". - On success, the application token is invalidated immediately.
Notes for External Engineers
- Linked account first – Ensure the payout destination is already linked (e.g. via the link-account widget/API) and that you have the correct
linkedAccountIdfor the entity’s SPEND wallet. - No MFA – This external payout endpoint does not require MFA. Omit
mfaCodefrom the request. - RTP for faster bank payouts – For bank linked accounts, send
routingType: "RTP"to use real-time payment when supported. - Fees – Fees depend on payout method and configuration. The response
data.feesanddata.amountreflect the fee and total debit. - Async outcome – Success means “queued”; final success/failure may be delivered asynchronously (e.g. webhooks). Use your transaction/withdrawal status APIs or webhooks to track final state.
- Rate limit – 1 request per minute per user (and IP). Design retries and UX accordingly.
- Idempotency – The API does not expose idempotency keys. Retrying the same request can create multiple withdrawals. Implement your own idempotency (e.g. linkedAccountId + amount + reason + timestamp) if you need to avoid duplicates.