Use CasesContractor Payouts

Contractor payouts

Pay contractors in stablecoins by giving each one a dedicated USD account that converts and delivers automatically.

Your customers are the people getting paid. Each one is verified once, gets a dedicated USD bank account, and receives stablecoins whenever the payer sends money to it.

The shape

Build order

StepCallNotes
1. Onboard the contractorPOST /api/customers with kind: "individual" and endorsements: ["endo_usd"]Requesting endo_usd needs email and phone, already on the customer or in the same request. Send tax_id and tax_residence_country too: the review needs them
2. Submit for verificationPOST /api/customers/{customer_id}/verificationsThe first submission. We hold documents until it, and a later PATCH that changes something resubmits by itself
3. Create their walletPOST /api/customers/{customer_id}/walletsNeeds an approved endorsement and your registered keys
4. Create their accountPOST /api/customers/{customer_id}/virtual_accounts with a wallet destination{"kind": "wallet", "asset": "usdc", "wallet_id": "wal_..."}
5. Show the deposit detailsdeposit_instructions from step 4Give them to the payer verbatim
6. Let them cash outPOST /api/wallets/{wallet_id}/operations, then authorizeSee Sending Funds

Steps 3 and 4 are in that order deliberately: a wallet destination needs the wallet to exist first.

Why a wallet destination rather than an address

You can deliver straight to an address the contractor gives you, which is simpler for a one-off payout. A held wallet is worth the extra setup when you want to:

  • show a balance in your product, read from the chain rather than tracked by you;
  • show history at GET /api/wallets/{wallet_id}/history, including money the contractor received from anywhere else;
  • let them send without leaving your app.

If none of those apply, use {"kind": "address", ...} and skip the wallet work entirely.

What to watch

  • endorsement.request_for_information drives most of your support load, because contractors submit unusable selfies. Build the fix-it screen from the requirement buckets before launch. See Verification needs more information.
  • deposit.received tells you the payer paid. payout.completed carries the tx_hash worth showing the contractor.
  • wallet_transaction.created (with kind: "deposit") fires for money that arrived at the address without any payer of yours being involved. Contractors do get paid from elsewhere, and your ledger should not be surprised by it.

Fees

Set partner_fee_bps per account to price contractors individually. It is charged in bps on each deposit, netted from the delivery, and credited to your balance in real time. On the standard plan our own conversion fee is metered to your monthly invoice, so it does not reduce the delivery. See Fees & Quotes.

The failure you should design for

A payer is ready to pay before the contractor's verification is approved. The account cannot exist yet, so there is nothing to send to. Handle it in your product: publish deposit instructions only after endorsement.approved fires, and until then tell the payer the contractor is still onboarding.