# Mass crypto payouts: CSV of up to 1,000 rows or the API

> Send mass crypto payouts with CryptoLike: a CSV of up to 1,000 rows confirmed with one 2FA code, or the API with payout_id. Whitelist, approvals, fees, errors.

Source: https://cryptolike.net/guides/crypto-mass-payouts
Published: 2026-09-24 · Updated: 2026-10-06 · Author: CryptoLike team

CryptoLike sends mass crypto payouts two ways: upload a CSV of up to 1,000 rows in the cabinet and confirm the whole file with one 2FA code, or create payouts through the API, one request each with your own `payout_id` so a retry never pays twice. Both draw on one balance, with the same fees, whitelist and approval rules.

## CSV or API: which one to use

CryptoLike offers the CSV upload for finance teams that pay from a spreadsheet and the API for systems that pay automatically: affiliate programmes, marketplaces, withdrawals of user balances. The CSV is all or nothing — one bad row rejects the file; the API creates each payout on its own, so your code handles every answer.

| Aspect | CSV in the cabinet | API |
|---|---|---|
| Who uses it | An owner, admin or finance member with 2FA | Your server with an API key that has `withdraw` |
| Size | Up to 1,000 rows and 1 MB per file, one asset per file | One payout per `POST /v1/withdrawals`; 600 requests/min per key by default |
| Confirmation | One 2FA code for the whole file | The key's `withdraw` permission |
| Validation | Every row first; any error creates nothing | Per payout |
| Repeats | Duplicate `payout_id` in the file or already used is a row error | The same `payout_id` returns the existing payout |
| Second approval | Rows over your threshold wait for another owner or admin | Not applied to API keys |
| Result | Batch report, then each payout's status | Response, `withdrawal.*` webhooks, `GET /v1/withdrawals/{id}` |

The business view of this scenario is on [mass payouts](https://cryptolike.net/use-cases/mass-payouts).

## Before you start

CryptoLike pays out only from a verified account: without account verification (KYB) every payout answers `403 kyb_required`. You also need an available balance in the payout asset, two-factor authentication for the people who create or approve payouts in the cabinet, and, for the API, a key with the `withdraw` permission — owners and admins grant it; a developer can request it, and an owner or admin approves the request.

## 1. Put payout addresses on the whitelist

CryptoLike's [payout whitelist](https://cryptolike.net/glossary/payout-whitelist) limits payouts to addresses you approved. In the cabinet open Withdrawals → Whitelist → Add address and confirm with a 2FA code. A new address activates after the delay set for your account (24 hours by default), so a stolen session cannot redirect funds at once. Revoking an address takes effect immediately.

With enforcement switched on, the cabinet, the Telegram bot and API keys alike accept only active whitelisted addresses; anything else answers `403`. A whitelist error on a row? Check the asset and the activation time of that address.

## 2. Estimate the fees and check the balance

CryptoLike shows the cost before anything moves: `POST /v1/withdrawals/estimate` with the asset and amount returns the platform fee, the reserved network fee, `total_debit` and the minimum amount. For a token such as USDT the network fee is converted into the payout asset, so every figure is in the same unit. A CSV upload uses one estimate per file.

`total_debit` = amount + platform fee + reserved network fee; it moves from `available` to `hold` when the payout is created. Fee schedule: [pricing](https://cryptolike.net/pricing). No estimate available? The payout is not created — retry later.

## 3. Prepare the CSV file

CryptoLike reads a CSV with the columns `address,amount[,payout_id[,comment]]`: the address and the amount are required, your payout id and a comment are optional. A header row with `address` is skipped, empty lines are ignored, and one file holds up to 1,000 rows of one asset. Amounts are decimals with no more digits than the asset has.

```csv
address,amount,payout_id,comment
TXYZ...1,125.50,aff-2026-09-001,September commission
TXYZ...2,80,aff-2026-09-002,September commission
```

Give every row a `payout_id`: it links the payout to your records and stops it from being created twice. More than 1,000 rows? Split the file.

## 4. Upload the file and confirm with one code

CryptoLike checks every row before creating anything: address format, whitelist, minimum, screening of the destination and duplicate `payout_id` values. In the cabinet open Withdrawals → Upload CSV, choose the asset, drop the file and review the preview with the row count and the total, then enter one 2FA code for the whole batch.

A valid file creates every payout in one transaction: «Batch created: N withdrawals queued.» Any bad row rejects the whole file — «Batch rejected: N rows with errors. Nothing was created.» — with a report of row, field and error. The same happens when the balance does not cover the file. Fix the rows and upload again; the rejected batch stays in the Batches tab.

## 5. Or send payouts through the API

CryptoLike's API creates one payout per `POST /v1/withdrawals` with `coin_id`, `amount`, `to_address` and your `payout_id`. Repeating the request with the same asset, amount and address returns the existing payout instead of paying twice; the same `payout_id` with other parameters answers `409`. Add an [Idempotency-Key](https://cryptolike.net/glossary/idempotency-key) for exact replays.

```ts
const payout = await api.withdrawals.create(
  { coin_id: usdtTrc20Id, amount: "125.50", to_address: "T...", payout_id: "aff-2026-09-001" },
  "aff-2026-09-001",
);
```

Send payouts at a steady pace: the default limit is 600 requests per minute per key, and a `429` tells you how long to wait in `Retry-After`. Full reference: [API docs](https://cryptolike.net/docs/api).

## 6. Approve large payouts and watch review

CryptoLike holds payouts that need a person. A payout created in the cabinet or the Telegram bot, CSV rows included, over your [dual-approval](https://cryptolike.net/glossary/dual-approval) threshold waits in `awaiting_approval` until another owner or admin approves it; the creator cannot. Limits and unusual patterns send a payout to `review`, which usually finishes within 24 hours.

Approve in the cabinet (Withdrawals → Approvals) or the Telegram bot with a 2FA code. The threshold is per asset and does not apply to API keys: granting `withdraw` to a key is the decision.

## 7. Track every payout to the end

CryptoLike reports each payout by status and by webhook: `withdrawal.processing`, `withdrawal.completed`, `withdrawal.failed` and `withdrawal.rejected` are enough to follow it to the end. `completed` means the transaction is confirmed and the fees are charged; `failed`, `rejected` and `cancelled` return the whole hold to your available balance.

| Status | What it means | What to do |
|---|---|---|
| `pending` | Funds on hold, queued | Cancel if needed |
| `review` | A manual check, usually under 24 h | Wait, or cancel |
| `awaiting_approval` | Waiting for a second owner or admin | Approve from another account |
| `processing` | Being signed and sent; cannot be cancelled | Wait |
| `broadcast` | In the network, `txid` known | Wait for confirmations |
| `completed` | Confirmed and charged | Nothing |
| `failed` | The network refused the transaction; funds returned | Create a new payout |
| `rejected` | Refused on review; funds returned | Check the destination or ask support |
| `cancelled` | You cancelled it; funds returned | Nothing |

`GET /v1/withdrawals` filters by `batch_id` or `payout_id` and exports CSV or XLSX for reconciliation.

## Errors and what to do

CryptoLike returns payout errors in one envelope with an HTTP status, a `code` and `details`; a rejected CSV comes back as a batch with `error_rows` instead. Each case has a recovery step, and a refused payout never leaves funds on hold. The full list is in the [API reference](https://cryptolike.net/docs/api).

| HTTP · code | What happened | What to do |
|---|---|---|
| `403 kyb_required` | The account is not verified | Complete account verification in the cabinet |
| `403 forbidden` | The whitelist is enforced and the address is not active on it | Add it and wait for activation, or switch enforcement off |
| `403 auth.permission_denied` | The key lacks `withdraw` | Use a key with `withdraw` |
| `409 conflict`, `insufficient_funds` | `available` does not cover `total_debit` | Top up or pay out less |
| `409 conflict` on a known `payout_id` | Same id, other asset, amount or address | Use a new `payout_id`, or read the existing payout |
| `422 address_refused` | The platform does not accept this destination | Use another address |
| `413 payload_too_large` | The file is over 1 MiB | Split the file |
| `429 rate_limited` | Over the per-key limit | Wait `Retry-After` seconds |
| `503 unavailable` | Fee estimate or asset temporarily unavailable | Retry with backoff; nothing was created |

## FAQ

### How many payouts can one CSV file hold?

Up to 1,000 rows of one asset, confirmed with one 2FA code. For a longer list, CryptoLike takes several files, or create the payouts through the API.

### What happens if one row in the CSV is wrong?

Nothing is created. CryptoLike keeps the batch as rejected with a report of each bad row — row number, field and error — so you fix those rows and upload the file again. No funds are put on hold for a rejected file.

### Can a retry pay the same person twice?

No, if you send a `payout_id`. A repeated API request with the same `payout_id`, asset, amount and address returns the payout that already exists, and a CSV row whose `payout_id` was used before is rejected as a duplicate.

### Can I cancel a payout?

Yes, while it is `pending`, `review` or `awaiting_approval`: cancel it in the cabinet or with `POST /v1/withdrawals/{id}/cancel`, and the hold returns to your available balance. From `processing` on, the payout is being signed and sent and can no longer be cancelled.
