Sending one stablecoin payment is easy. Sending thousands a week, without ever paying someone twice and with the right people signing off, is where payout systems earn their keep.
Never pay twice
Every payout carries an externalId: your own id for it, such as the invoice or withdrawal number. Sending the same externalId again returns the existing transfer instead of creating a new one, so a timeout or a retry can never send money twice. See retry-safe payouts.
Batches
You can send up to 100 payouts in one call. Each needs its own externalId. A batch isn't all-or-nothing: each payout succeeds or fails on its own, and re-sending the whole batch is safe because the ones already created are returned as they are.
const result = await valtu.transfers.createBatch(payouts.map((p) => ({
walletId: payoutsWalletId, asset: "USDT-TRC20", amount: p.amount, to: p.address, externalId: p.id,
})));
Approvals that match your risk
Policies decide what goes straight out and what needs people:
- small payouts from an API key can be allowed automatically;
- larger ones can need one or more approvals from an approval group;
- the person (or API key) that proposed a payout can never approve it themselves.
Approvers confirm with passkeys, and the approval is bound to the exact amount and destination. See how a payout gets signed.
Keeping the queue moving
Payouts from one wallet on one network go out in order. If one needs an approval, that wallet's queue on that network waits while other wallets and networks keep going. Network fees for token payouts can come from a gas wallet, so a payout wallet that holds only USDT still works.
Status changes arrive as signed webhooks (transfer.confirmed, transfer.failed and others), so your system can mark each payout paid once the network has confirmed it.