Sending crypto payouts at scale: batches, approvals and limits

Paying hundreds of sellers or employees in USDT is mostly an operations problem: never paying twice, getting the right people to approve, and keeping a wallet's queue moving.

The Valtu team

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.

Keep reading

More from the blog

bitcoin · payouts Stuck Bitcoin payouts: how replace-by-fee gets them moving When Bitcoin fees jump after a payout is sent, it can sit unconfirmed for hours. Replace-by-fee resends the same payment with a higher fee, without paying twice. developers · python The Valtu Python SDK is on PyPI pip install valtu: a signed API client, webhook verification and enclave attestation checks for Python 3.9 and later, with the same behavior as the TypeScript wallet kit. networks · developers One address, five networks: how EVM deposit addresses work With Valtu, a customer's 0x address is the same on Ethereum, BNB Chain, Polygon, Base and Lisk. Here is why that works, and what it means for deposits sent on any of them.

Start with a test workspace today.

Same dashboard, same API, free test coins. Go live when your team is ready.