Withdrawals & Conversion
How hosts cash out diamonds, and the conversion escape hatch.
Last updated Thu Jul 16 2026 00:00:00 GMT+0000 (Coordinated Universal Time)
TL;DR -Hosts cash out earned diamonds for real money once past a 72-hour hold and a $25 minimum -or convert them back into (non-earning) coins to spend themselves.
Who this is for -Business & Product: how cash-out and conversion work, and the margin math (all sections -they're short). Backend & Operations engineers: the endpoints, ledger rows, and payout status lifecycle.
This is the end of the money's journey: turning a host's diamonds (the currency they earn from gifts) into actual cash in their bank. Before that can happen, freshly earned diamonds have to clear a waiting period. There's also an "escape hatch" for hosts who'd rather spend their earnings than withdraw them.
In plain terms: how cashing out works
When a host earns diamonds, they aren't instantly withdrawable. They sit in a pending state for 72 hours -a cooling-off window that covers refunds and chargebacks -then become available. Once a host has at least $25 worth of available diamonds (5,000 of them), they can request a payout. New hosts have a weekly cap while the platform builds trust in the account.
Alternatively, a host can convert diamonds straight into coins to spend in other people's rooms. Those coins are "bonus" coins -spendable, but they never earn anyone diamonds, so there's no way to loop value back into cash.
How it works: settlement first
Gift earnings land as pending diamonds and mature to available
after the 72-hour hold (DiamondSettlement.settleAt). Settlement is lazy:
any wallet read, conversion, or withdrawal first promotes matured rows —
inside a transaction, with a DIAMOND_SETTLED ledger row. No cron needed.
How it works: withdrawal flow
A cash-out is a single call, POST /withdrawals { diamonds }, that runs
these steps in order:
- Settle matured diamonds.
- Check available balance and the $25 minimum (5,000 diamonds).
- New-host cap: accounts under 30 days are limited to $100/week.
- Create the
Withdrawalrow (status lifecycle: requested → approved → paid, or rejected/reversed) and hold the diamonds (WITHDRAWAL_HOLDledger row).
Admin review happens in this portal (Withdrawals page); payout status
transitions write WITHDRAWAL_PAID / WITHDRAWAL_REVERSED rows. Stripe
Connect is scaffolded as the payout rail.
How it works: diamond → coin conversion
The escape hatch. POST /wallet/diamonds/convert-to-coins { diamonds }:
- Rate 2:1, amount must be a multiple of 2.
- Output is bonus coins -spendable but never diamond-generating, so no conversion loop exists.
- Ledger row
DIAMOND_TO_COIN_CONVERSIONrecords both sides.
Cash-out math sanity check
To see how the margin actually lands, follow the smallest purchase all the way through to a payout.
A $0.99 purchase (70 coins), fully gifted: host receives 35 diamonds =
$0.175 cash value. Platform gross after ~30% store fee ≈ $0.69, payout
$0.175 -the margin structure the 25%-payout model is built around. All
constants live in economy.constants.ts; change them there and every flow
(and rate snapshot) follows.
Related pages
- Economy -the rates and settlement hold this page relies on.
- Gifting -where the diamonds being withdrawn come from.
- Refunds -why the 72h hold matters before payout.
- Creator program -planned tiers and bonuses that add to withdrawable diamonds.