Flow
An integration has seven steps. Steps 2 and 3 involve a manual review on our side, so they are asynchronous: poll therefresh endpoints until status is ready.
1
Register a Sender
A Sender is the payer named on the bank transfer: an enterprise or an individual. One organization can have many Senders.
Register Senders
2
Submit the Sender's payer details
Upload KYC documents, then submit the payer details. Wait for
status: ready, using Refresh a Sender to re-check.
Upload a Sender file, enterprise or personal payer details.3
Register a Beneficiary
Who gets paid. Wait for
status: ready, using Refresh a Beneficiary to re-check.
Register Beneficiaries4
Fetch the purpose codes
Every order needs a
purpose_code that is valid for its Sender and Beneficiary.
Get purpose codes5
Create a batch
A batch holds one or more orders. Each order comes back quoted in USDT.
Create a draft batch
6
Fund and confirm
Make sure your payout vault holds enough USDT, then confirm the batch.
Get the funding address, Confirm a batch
7
Track the batch
Follow the batch until every order is
COMPLETED or FAILED.
Get a batch, Refresh a batchConventions
- Base path:
/api/v2/payouts. Your organization must have the Payout product enabled. Check product entitlements showspayoutas enabled. - Authentication: the same signed-request scheme as the rest of the Mansa API (API key plus a signed JWT per request). Multipart uploads are signed as if the body were
{}. - Naming: all request and response fields are
snake_case. Two exceptions: thefileTypemultipart form field and thebeneficiaryIdquery parameter on Get purpose codes. - Amounts are decimal strings (for example
"100.00"), never numbers. - Timestamps are ISO-8601 UTC strings.
- Partner details are never exposed. Statuses and error messages are Mansa’s own.
Senders
A Sender needs three calls before it can be used on an order: register it, upload its documents, then submit its payer details.- Register Senders. Each Sender starts
pending. - Upload a Sender file for each document. A Sender needs 1 to 10 files, and each upload returns a
file_id. - Submit payer details with the
file_idvalues inkyc_file_ids: enterprise for anenterpriseSender, personal for anindividualone. For an individual, use a value from Get ID types asid_type.
Review is manual and there is no callback. Call Refresh a Sender to re-check; it returns the Sender.
Beneficiaries
A Beneficiary is not tied to a Sender: any Beneficiary can be paid from any of your Senders. The Sender is chosen per order.- A bank Beneficiary needs its own address (
beneficiary_country_code,beneficiary_province,beneficiary_city,beneficiary_address,beneficiary_postcode), separate from the bank’s. subject_typeiscorporateorindividual. Individuals also needfirst_nameandlast_name.intermediary_bank_nameandintermediary_bank_swiftare optional.beneficiary_typecan also becrypto(withchain_typeTRC20orERC20, and the address inaccount_number) orplatform.
pending and use the same statuses as Senders. Use Refresh a Beneficiary to re-check.
Purpose codes
Every order needs apurpose_code that is valid for its Sender and Beneficiary. Always fetch the list with Get purpose codes and use the code exactly as returned. Do not hard-code it.
Batches and orders
A batch is the unit of submission: always one or more orders. A single payment is a batch of one.Create
Create a draft batch quotes every order. Nothing is charged and no funds move until you confirm.beneficiary_amountis what the Beneficiary receives, inbeneficiary_currency.beneficiary_currencyis one of USD, EUR, CNH, AUD, CAD, HKD, JPY, NZD, SGD, GBP or AED. Every order in a batch must use the same currency.fee_typeisSHA(bank charges shared with the Beneficiary) orOUR(you pay all bank charges). Your organization’s configuration decides which are allowed.- The Sender must be
readyto quote. The Beneficiary must bereadyby the time you confirm.
DRAFT with a quote: fee_amount and fee_currency (the wire fee for the chosen fee_type, always USD), and source_amount and source_currency (the total USDT the order costs, all fees included). Edit a draft with Edit a draft order; it is re-quoted.
The batch-level
source_amount is meant to be the sum of its orders’ source_amount, but currently returns null before confirm and "0.000000" after. Use the orders’ own source_amount until this is fixed.Fund and confirm
Check the vault with Get the funding address first. Confirming moves the batch’s totalsource_amount out of your payout vault in one transfer.
- Before any money moves, confirm checks that every Beneficiary is
readyand each bank order’spurpose_codeis currently valid for its Sender and Beneficiary. Either failure rejects the confirm. - An order whose deposit hasn’t landed within 2 hours of confirmation expires to
CANCELLED_EXPIRED(seeexpires_at). - Cancel an order works while it is
DRAFTorAWAITING_DEPOSIT.
Track
Get a batch and Refresh a batch return the batch and all its orders. Refresh an order returns a single order. AFAILED order carries a generic failure_message; Mansa follows up directly. List batches is paginated and returns batches without their orders.
uetr on an order holds the SWIFT UETR once the bank network reports one. It may stay null after COMPLETED.
Statuses
Order
Batch
AWAITING_CONFIRMATION, IN_PROGRESS, COMPLETED, PARTIALLY_COMPLETED, FAILED, CANCELLED_EXPIRED.
Errors
Failed calls return a non-2xx HTTP status and a JSON body withstatusCode and message. Use the HTTP status to branch; treat message as human-readable text, not a stable code.
message as an array:
Money-moving calls (
confirm) are checked before any funds move, so a rejected confirm leaves the batch unchanged and can be retried after you fix the cause.
Changes from earlier versions
If you integrated against an earlier release, these changes are breaking:
Additive changes: new Beneficiary fields (
subject_type, beneficiary_* address, intermediary bank); new order fields fee_currency and uetr; new batch field source_amount; new endpoints Get ID types, Get purpose codes and the four refresh endpoints.
