What 'hot' and 'cold' actually mean
A wallet is a private key plus the software that signs transactions with it. The hot-versus-cold distinction is entirely about where that key lives relative to the internet. A hot wallet keeps the key on a system that is online — a server, a browser extension, a phone — so it can sign and broadcast a transaction in seconds. A cold wallet keeps the key on hardware that never touches a networked machine; to spend, you physically move a signed transaction across an air gap.
Convenience and exposure are the same axis, pulling in opposite directions. The hot wallet that lets you pay an affiliate the instant a request comes in is, for that same reason, a key an intruder can use the instant they reach the box it sits on. The cold wallet no remote attacker can touch is also the one that takes a human, a device, and a deliberate ceremony to spend from. No setting gives you both maximum speed and zero exposure — there is only where you place the dial.
For a merchant the framing is operational, not philosophical. Money flowing through your business has a rhythm: payments arrive, balances accumulate, payouts go out, a float sits ready for refunds. The right design keeps only the working float somewhere fast, and everything above it beyond an attacker's reach in a single compromised request.
- Hot wallet: key on an online system; signs instantly; exposed whenever that system is.
- Cold wallet: key offline / air-gapped; signing is a deliberate, human ceremony.
- Speed of access and breadth of exposure are one axis, not two dials.
- Sound merchant design splits a small fast float from a larger guarded reserve.
The tradeoff, line by line
It helps to see the two models side by side on the dimensions a finance or security owner actually weighs: how fast you can move money, how much is reachable in a breach, and how much operational friction you sign up for. Neither column is 'correct' — they are tuned for different jobs, and most real setups are a blend: a deliberately small hot balance for day-to-day disbursement, backed by a cold reserve that only a manual, audited process can draw down. Read the table as a spectrum, not a binary.
| Dimension | Hot wallet | Cold wallet |
|---|---|---|
| Key location | Online system that can sign on demand. | Offline / air-gapped hardware, signed across a gap. |
| Speed to move funds | Seconds — good for automated, frequent payouts. | Minutes to hours — a human ceremony each time. |
| Exposure in a breach | Whatever balance it holds is reachable the moment the host is compromised. | Funds are unreachable without physical access to the device. |
| Best fit | The working float: refunds, day-to-day payouts, operational liquidity. | The reserve: value you are not actively disbursing this hour. |
| Main failure mode | A leaked server key drains the balance instantly. | Lost device or seed phrase locks you out — backup discipline is critical. |
Where halfin changes the question
When you take payments through halfin you are not, day-to-day, holding raw private keys and deciding which one is hot. You operate against a balance. The mental model shifts from 'which wallet do I keep online' to 'who and what is allowed to move my balance, and is every move accountable'.
That does not make the hot/cold tradeoff vanish — it relocates it. The exposure that used to live in a server-side hot wallet now lives in your credentials and your approval process: a leaked API key is the new hot-wallet key, and an unguarded approval step is the new always-online signer. So the security work for a halfin merchant is concrete and bounded — scope your keys, gate your payouts, and read your audit trail. Those three controls are the custody boundary you actually administer.
Be precise about what that boundary is and is not. halfin's custody story is signing, permissions, and audit — the mechanisms below — not a blanket guarantee that funds can never be lost, and this guide does not claim one. Its value is specific, inspectable controls instead of an opaque vault you must trust, mapped cleanly onto the hot/cold instinct you already have.
- You interact with a balance, not a private key you must keep hot.
- The exposure relocates from a server wallet to your API keys and approval step.
- The custody boundary you administer is signing + permissions + audit — nothing more is promised.
Permissions: scope keys like you'd size a hot float
The single most useful habit a halfin merchant can adopt is to stop using one all-powerful API key. halfin keys carry scoped permissions: you can mint a key that reads invoices but cannot initiate a payout, and a separate key that stages payouts but cannot touch settings. Scoping keys is the direct analogue of keeping only a small float hot — you shrink what any single credential can do if it leaks.
Map a key to the job and nothing else. Your storefront, which only ever creates invoices, gets an invoicing-scoped key — exfiltrate it from a frontend or a log and the attacker can create invoices, not drain your balance. Your reporting job gets a read-only key. The one service that legitimately moves money out gets a payouts-scoped key, held in a secret manager, never in source control, and rotated the moment you suspect exposure. Scoping is what makes a leaked analytics credential incapable of initiating a payout.
When you do create a payout programmatically, the request itself is mundane — and that is the point. The dangerous part is not the call but who holds the key that can make it and what approval stands behind it. The example below stages a single payout with a payouts-scoped key and a deterministic idempotency_key in the body, so a retry never creates a second payment.
# Stage a payout with a tightly SCOPED key — not your one master key.
# The idempotency_key is a snake_case BODY field, so a retried request
# never creates a second payment. Note: this only STAGES the payout;
# funds do not move until it is released for approval in the dashboard.
curl -X POST https://api.thehalfin.com/api/v1/payouts \
-H "X-API-Key: $HALFIN_PAYOUTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currency": "USDT_TRC20",
"amount": "250.00",
"destination": "TXk...recipient-address",
"idempotency_key": "acct_4821:payout-2026-06"
}'
# A leaked invoicing-scoped or read-only key CANNOT make this call.
# See docs.thehalfin.com for the full payout request and response schema.Signing and approval: your cold-wallet ceremony, kept
The reason a cold wallet feels safe is the ceremony — moving real money out takes a deliberate, human act that an automated attacker cannot perform alone. halfin preserves that ceremony for payouts without forcing you offline. A payout you create through the API does not move funds; it enters a pending-approval state and is released from the dashboard. The high-throughput path that stages payouts is deliberately separated from the human control point that signs them off.
That separation is exactly the hot/cold split, expressed as process instead of hardware. Your loop can stage a thousand payouts unattended — fast, like a hot wallet — but nothing leaves your balance until a person with the right access approves the run, so a fully compromised payouts key only buys an attacker the ability to propose payments, not release them. Use the gap: before approval, reconcile the count and per-currency totals of the staged run against your own ledger. Catching a duplicated source row or a fat-fingered amount here is cheap; catching it after approval is a refund problem.
Keep the approving identity tightly held and distinct from the one that owns the API keys. The whole benefit collapses if one person and one compromised session can both stage and approve — do not merge the two for convenience.
- Creating a payout does not move money — it stages a proposal for approval.
- Approval is the human ceremony, the process-level equivalent of touching a cold wallet.
- A compromised payouts key can propose payments but cannot release them alone.
- Reconcile staged count and per-currency totals against your ledger before approving.
Audit: make every movement accountable after the fact
Signing and permissions decide who can move money; audit decides whether you can ever explain what happened. The third leg of the custody boundary is that balance movements are observable and reconcilable — through the dashboard, the REST API, and signed webhook events. It turns 'we think the balances are fine' into a verifiable answer for every credit and debit.
Drive your records from signed events, not optimistic guesses. A confirmed invoice and a settled payout each emit a webhook — invoice.paid and payout.completed among them — and the discipline that makes audit trustworthy is the one that makes webhooks safe: verify the HMAC signature over the raw request bytes with a constant-time comparison before you act, because the endpoint is public and an unsigned request is not a halfin event. Then dedupe on the stable event id so a redelivered event updates your ledger exactly once. Crediting is reorg-aware and respects per-chain confirmation thresholds, so a 'paid' or 'completed' event reflects value that actually held on-chain.
Read the audit trail on a normal day, not only after an incident. If finance can match every balance change to a verified event, an anomaly — a payout you did not stage, a credit that ties to no invoice — surfaces in routine reconciliation instead of a crisis. Scoped keys (who could act), approval (who signed off), and a verified event log (what actually moved) are the whole boundary, only as strong as the weakest of the three.
A practical setup that respects the tradeoff
Pulling it together, here is a configuration that keeps the hot/cold instinct intact while you operate against a halfin balance — no raw keys to manage, just scoping, separating, and watching. Start minimal and tighten from there: it is far easier to grant a missing permission than to claw back an over-broad key after it has leaked.
- Size your operational float to genuine throughput and no larger, the way you would size a hot wallet.
- Issue one scoped key per job: invoicing for the storefront, read-only for reporting, payouts for the disbursement service.
- Keep the payouts key in a secret manager, never in source control, and rotate it on any suspicion of exposure.
- Leave payout approval as a human step, and keep the approving identity separate from the key-holding service.
- Reconcile staged payout totals against your ledger before approval; reconcile settled movements against verified webhooks after.
- Verify the HMAC signature on every webhook over the raw bytes, and dedupe on the event id so redelivery is a no-op.
- Review the balance audit trail as routine, so an unexplained movement is caught in reconciliation, not in an incident.