# Protect crypto payouts: address whitelist and a second approval

> Set up CryptoLike payout controls step by step: 2FA, an address whitelist with a 24-hour delay, a second approval above your threshold, narrow API keys and alerts.

Source: https://cryptolike.net/guides/payout-whitelist-dual-approval
Published: 2026-09-24 · Updated: 2026-10-06 · Author: CryptoLike team

CryptoLike protects payouts with controls you switch on in the cabinet: a fresh 2FA code for every payout made in the cabinet or the Telegram bot, an address whitelist where a new address becomes usable only 24 hours after it is added, and a second approval by another owner or admin above an amount you set per asset. Payouts through the API need no 2FA code: they are authorised by a key with the `withdraw` permission, so limit such keys to your servers' IPs and enforce the whitelist. Together with API keys limited to what they need, they make it hard for a stolen password, session or key to send your money anywhere. This guide sets them up in about 15 minutes, plus the 24-hour wait for new addresses.

## Which control stops which attack

Each CryptoLike payout control closes a different path. 2FA stops someone who only has your password. The whitelist stops a payout to an address you did not add a day earlier. The second approval stops one person — or one compromised account — from sending a large amount alone. Narrow API keys stop a leaked shop key from paying out at all.

| Control | Stops | Who can change it | Default |
|---|---|---|---|
| 2FA on cabinet and Telegram payouts | A payout with a stolen password or session alone | Each user, in Profile & security | Required: without 2FA, cabinet and Telegram payouts are refused |
| Address whitelist | A payout to an address added less than 24 hours ago, or not added at all | Enforcing: owner or admin, with 2FA. Addresses: owner, admin or finance; adding needs 2FA, removing does not | Off |
| Second approval | A payout above your threshold created by one person | Owner or admin, with 2FA | Off |
| API key permissions and IP list | A leaked key paying out, or used from another server | Owner, admin or developer; `withdraw` is granted by an owner or admin with their 2FA — a developer only requests it | Set per key |
| Review limits | Unusual volume: above per-payout or daily limits, a large payout to a new address, a burst of payouts | The platform, per account | Set per account |

Checked against the CryptoLike API and cabinet on 2026-09-24. The whole list of platform controls is on the [security page](https://cryptolike.net/security).

## Before you start

You need an owner or admin role in a verified CryptoLike account: payouts start after account verification ([KYB](https://cryptolike.net/glossary/kyb)). A finance team member can add whitelist addresses and create payouts, but only owners and admins change the payout settings and give the second approval. Every person who touches payouts needs an authenticator app for 2FA.

Know the addresses you pay out to — your exchange accounts, your own cold wallet, regular contractors — and the network of each: USDT on TRON and USDT on Ethereum are different assets with different addresses.

## 1. Turn on 2FA for everyone who pays out

Open **Profile & security** and turn on two-factor authentication with an authenticator app; save the 10 recovery codes somewhere offline. Without 2FA, CryptoLike refuses to create a payout: the cabinet answers `403` with `mfa_setup_required`. Ask every owner, admin and finance user to do the same before you go further.

With 2FA on, every cabinet or Telegram payout, every new whitelist address and every change of payout settings asks for a fresh code, and a code cannot be used twice. Removing an address needs no code. Repeated wrong codes lock the account, each new lock for longer, and end every session. The lock also counts wrong codes entered in the Telegram bot.

## 2. Add the addresses you pay out to

Open **Withdrawals → Whitelist → Add address**, choose the asset, paste the address, give it a label such as "Treasury cold wallet" and confirm with your 2FA code. The address is validated for the asset's network and saved as inactive: it becomes usable 24 hours after it is added, so a stolen session cannot redirect payouts at once.

Add every regular destination now, because of that delay. Removing an address takes effect immediately — removing moves no money. Each add and removal is written to the security log, and team members with Telegram notifications receive a message about whitelist changes. API keys can never change the whitelist.

## 3. Enforce the whitelist

Open **Withdrawals → Settings**, switch on **Enforce the address whitelist** and confirm with 2FA. From now on, payouts from the cabinet, the Telegram bot and the API go only to active whitelisted addresses. A payout to any other address is refused: `403 forbidden`, "destination address is not on the active withdrawal whitelist", with `details.field: to_address`.

Enforce it only after your addresses are active, or regular payouts will be refused for the first 24 hours. In the Telegram bot, an enforced whitelist also changes the dialogue: the bot offers your active addresses as buttons instead of asking you to type one.

## 4. Set the second approval threshold

In **Withdrawals → Settings → Dual approval threshold**, enter an amount per asset — for example 1,000 for USDT on TRON — and confirm with 2FA. A cabinet or Telegram payout above that amount waits in `awaiting_approval` until another owner or admin approves it; below the amount it goes through as usual. An empty threshold turns the check off for that asset.

The threshold applies to payouts created by a person. Payouts created with an API key do not wait for a second approval — protect them with the whitelist and the key's own limits (step 6). A payout waiting for approval keeps its amount on hold on your balance and can be cancelled until it is approved. See [second approval](https://cryptolike.net/glossary/dual-approval) in the glossary.

## 5. Approve a payout as the second person

The second owner or admin opens **Withdrawals → Approvals**, checks the destination, amount and estimate, presses **Approve** and enters a 2FA code; the payout is then queued for signing. The same approval is available on the payout card in the Telegram bot. The person who created the payout cannot approve it: the API answers `409 conflict` with `reason: same_user`.

What the approver should check before pressing Approve:

- **The destination** is the expected whitelisted address for this asset and network.
- **The amount and `total_debit`**: the estimate shows the platform fee, the reserved network fee and the total that leaves the balance.
- **The reason** for the payout, from the comment or your own records.

## 6. Keep API keys narrow

Open **Developers → API keys** and review every key. A shop, a plugin or a reporting tool needs `create_invoice` and `read` only; give `withdraw` only to the system that pays out, and fill in the key's **IP whitelist** with the addresses of the servers that call the API. A request from another IP is refused with `403 auth.ip_not_allowed`.

Owners, admins and developers can manage API keys, but only an owner or admin grants `withdraw`, with a fresh 2FA code. A developer who needs a payout key requests the permission: the key works for its other permissions at once and refuses payouts with `403 withdraw_pending_approval` until an owner or admin — not the person who asked — approves the request in **Developers → API keys**. Requests wait there in the **Approval requests** block, with a counter next to the menu item: who asked and when, the key, the IP whitelist the request was made with and when the request expires. The approval covers that whitelist: if the key's whitelist has changed since, the approval is refused. A developer who changes the IP whitelist of a payout key confirms with a 2FA code, and the key stops paying out until an owner or admin approves a new request for the new list. **Approve** asks for the approver's 2FA code and leaves the key's secret as it is; **Reject** takes an optional reason. The key itself shows **Payouts: awaiting approval**, and later **rejected** or **expired**, so the developer sees the answer. A request without a decision expires after 72 hours by default. When the person who asked or the person who approved leaves the team or changes role, the key loses `withdraw`. A payout sent through the API should carry your own `payout_id`: repeating the request with the same asset, amount and address returns the same payout instead of creating a second one, which protects against double payment when a request times out. How that works: [idempotency in payment APIs](https://cryptolike.net/blog/idempotency-in-payment-apis).

## 7. Test the setup with a small payout

Create a small payout to one of your whitelisted addresses and watch it go through each control. Then try a payout above the threshold, and approve it from a second account. Finally, check what you would see during an attack: a payout to an address that is not on the list must be refused.

| Test | Expected result |
|---|---|
| Small payout to an active whitelisted address | `pending`, then `processing`, `broadcast` and `completed` |
| Payout above the threshold | `awaiting_approval`; approved by the second person → `pending`, then `processing` |
| Approval by the creator | `409 conflict`, `reason: same_user` |
| Payout to an address that is not whitelisted | `403 forbidden`, `details.field: to_address` |
| Payout to an address added less than 24 hours ago | Refused the same way until the address activates |

Payout statuses arrive as `withdrawal.*` webhooks; mass payouts through a CSV file are validated against the same whitelist row by row — see [mass crypto payouts](https://cryptolike.net/guides/crypto-mass-payouts).

## What the platform checks on top of your controls

Your controls sit on top of checks CryptoLike runs on every payout. A payout above the per-payout or daily limit of your account, or an unusual pattern such as a large payout to a new address or a burst of payouts, goes to a manual review instead of being refused; the cabinet shows the reason. Payout destinations are screened when the payout is created and again before it is signed: a sanctioned address is refused, and a high-risk one goes to review.

After your approvals, the payout is signed by a separate signing service that signs only payouts in processing with a matching hold on your balance. How funds are kept between hot and cold storage is explained in [hot and cold wallets](https://cryptolike.net/blog/hot-and-cold-wallets).

## FAQ

### How long does a new whitelist address take to activate?

24 hours after it is added with a 2FA code. Until then payouts to it are refused while the whitelist is enforced. The delay gives you time to notice a change you did not make: whitelist changes are written to the security log and reported in Telegram notifications.

### Does the second approval apply to API payouts?

No. The threshold applies to payouts created by a person in the cabinet or the Telegram bot. API payouts are protected by the key's withdraw permission, its IP whitelist and, when enforced, the address whitelist, which applies to API keys too.

### Can the person who created a payout approve it?

No. The second approval must come from another owner or admin, and the database enforces that the approver differs from the creator. An attempt by the creator answers 409 conflict with reason same_user; the payout keeps waiting for a second person.

### Can someone with a stolen API key change the whitelist?

No. API keys cannot add or remove whitelist addresses or change payout settings. Those actions exist only in the cabinet: owners, admins and finance users add an address with a fresh 2FA code and can remove one without it; payout settings change only with an owner's or admin's code. Every change is written to the security log.

### What happens to the money while a payout waits for approval?

The amount, the platform fee and the reserved network fee stay on hold on your balance, so they cannot be spent twice. If nobody approves the payout, cancel it: the hold returns to your available balance and nothing is sent.
