About only1win
At only1win, we run a lucky-number game for phones: every player at a table holds a number, one block of the TRON chain picks the lucky one, and the winner takes the pool. A Global round every 60 seconds from ₹1, instant 1v1 / 1v5 / 1v10 tables and Friends Rooms — fair by design, settled in seconds, in rupees.
Partners put only1win inside their own website or app. Their users play as ordinary only1win players — with an only1win wallet, deposits and withdrawals handled by only1win — and the partner earns on every game those players play.
What you get
only1win is for players aged 18 and over. Partners must show the game only to adults and in places where real-money skill and chance games are allowed. See The frame for what the game itself asks on the first open.
Where to go next
- How it works — the whole flow in five lines.
- Become a partner — free for anyone: how to apply, what you receive, your first sign-in.
- Launch API — the only call you make; then The frame and Messages.
- Go-live checklist — before you flip the switch.
The flow
- Your server asks only1win for a launch URLTheir id on your platform + the mobile number, signed with your API key. One call per open.
- You open that URL in an iframeThe first time, the player confirms the mobile number with an SMS code (sent and paid for by only1win), ticks 18+ and starts playing. After that, every launch opens the game at once — no code.
- The player plays with a normal only1win walletThey deposit (UPI, bank, USDT) and withdraw on their own; only1win handles the money, KYC and support. You never touch player money.
- You earn the moment each game endsOn every game played through your platform — by a player you brought or an only1win player who simply plays there — credited to your partner wallet; withdraw in USDT whenever you like.
A few rules
- Phone numbers in the dashboard are masked; balances, bank and wallet details of players are never shown to partners.
- A launch URL works once and for 5 minutes — ask for a fresh one on every open.
- The player’s session inside your frame lasts 24 hours; when it ends, the game tells your page (
need_session) and you launch again. - Withdrawals are confirmed with an SMS code and are done on the web version — see Withdrawals.
- Where a game is played decides who earns. Every game inside your frame counts for you — whether the player is new to only1win or already had an account. The same player playing on another platform, or on only1win.bet directly, does not count for you.
How to apply
There is no form. Write in our Telegram discussion group that you want to integrate only1win — your platform’s name and site are enough — and a member of our team will contact you there and set everything up: your dashboard login, your API key and your game address.
It is 100 % free — for anyone. only1win never charges a fee, a deposit or any payment to become a partner, and never asks for money at any step. Anyone who asks you to pay — a “support manager”, an “agent”, a “verification fee” — is a fake. Talk to us only in the official group and channel above.
What you receive
- A dashboard login — an email (your sign-in name) and a first password.
- An API key id (
pk_…) and the secret (sk_…) — the secret is shown once; keep it on your server. - Your game address:
https://api.only1win.club/embed/<your-slug>— the launch URL points there.
Your first sign-in
- Open partner.only1win.club and sign in with the email and password you were given.
- Set a new password (at least 10 characters).
- Set up Google Authenticator — scan the QR, type the code, save the backup codes. Every sign-in asks the app’s code from then on, and so do payouts, the payout address and key rotation.
Several people can run the dashboard: add logins in Settings → Dashboard logins. Each has their own password and Authenticator.
What is in the dashboard
| Page | What it shows |
|---|---|
| Dashboard | Players, deposits, withdrawals, games, bets, fee, your share — Today · Yesterday · This month · the dates you pick |
| Players | Everyone who came from your platform: your player id, masked mobile, model, deposits, withdrawals, bets, won, last seen |
| Deposits · Withdrawals | Your players’ money in and out, by day — never a bank or wallet detail |
| Games · Earnings | Every game your players sat at, and what each one earned you |
| Payouts | Your wallet → USDT TRC20 to your saved address, live tracking |
| Settings | Logo, site URL, allowed origins, language, revenue model, payout address, API key, dashboard logins |
| Log | Every change on your account, by whom |
| Term | Meaning |
|---|---|
player_id | Your user’s id on your platform. The permanent link between your user and the only1win player; it never changes and never moves to another mobile number. |
| Launch URL | A one-time address for one player, good for 5 minutes, returned by the Launch API. You open it in your iframe. |
| Verified player | A player who confirmed the mobile number with an SMS code inside your frame once. Every later launch opens the game at once. |
| Linked account | Someone who already had an only1win account and verified it in your frame. They play through your platform like anyone else — and every game they play there counts for you. |
| Partner session | The player’s 24-hour session inside your frame. Every seat taken in it is marked as yours — that is how only1win knows which platform a game was played through. It never changes the account’s password, 2FA or devices. |
| Revenue model | Fixed share or Referral — see Revenue models. The model active when a player is created stays with that player forever. |
| Share | Your % (40 % by default) of only1win’s fee on a seat played through your platform, after any Refer & Earn commissions on that seat — per game. |
| Partner wallet | Where your earnings land, the moment each game ends. Withdraw from it in USDT, any time. |
| Site URL | Your website. Its origin may frame the game, and players in your app are sent there to withdraw. |
| Allowed origins | The exact https origins that may frame the game (https://play.example.com). Anything else is refused by the browser. |
JSON in, JSON out. Every call carries an HMAC-SHA256 signature over the exact bytes you post, so only your server can launch your players — never call it from a browser or an app.
Authorizations
pk_… from the dashboard → Settings → API key.ts + "." + nonce + "." + rawBody — the exact bytes you post, no re-serialising.Body
_ . : -, up to 64. The link between your user and the only1win player; stable forever.+919812345678 (India today).en or hi. The language the game opens in for this player.lobby (default), global, 1v1, 1v5, 1v10: where the frame opens.Response
{
"url": "https://api.only1win.club/embed/your-slug#c=…",
"expires_in": 300,
"status": "new"
}linked when this player_id already verified once (the frame opens straight into the game); new otherwise (the frame asks for the SMS code).Keep the secret on your server. If it ever leaks, rotate it in the dashboard → Settings → API key: the old key stops at once.
Errors
| Status | Error | Why |
|---|---|---|
| 401 | bad_signature | The signature does not match the bytes you posted, or the key is wrong |
| 401 | stale_timestamp | X-Partner-Ts is more than 60 s away from only1win’s clock |
| 401 | nonce_reused | The same nonce within 10 minutes |
| 401 | unknown_key | No such key id (rotated?) |
| 403 | partner_paused | Your platform is paused — contact only1win |
| 400 | invalid_player_id · invalid_phone · country_not_supported | The body |
| 409 | mobile_mismatch | This player_id is already linked to a different mobile number — the number of a linked player cannot change |
// Node 18+ — on YOUR server, never in the browser (the secret stays with you) import crypto from 'node:crypto'; const KEY_ID = 'pk_your_key_id', SECRET = process.env.O1W_SECRET; // dashboard → Settings → API key export async function launchUrl(player) { const body = JSON.stringify({ player_id: player.id, mobile: player.mobile, name: player.name, lang: 'hi', game: 'lobby' }); const ts = Math.floor(Date.now() / 1000), nonce = crypto.randomBytes(16).toString('hex'); const sig = crypto.createHmac('sha256', SECRET).update(ts + '.' + nonce + '.' + body).digest('hex'); const r = await fetch('https://api.only1win.club/api/partner/v1/launch', { method: 'POST', body, headers: { 'Content-Type': 'application/json', 'X-Partner-Key': KEY_ID, 'X-Partner-Ts': String(ts), 'X-Partner-Nonce': nonce, 'X-Partner-Sig': sig } }); const j = await r.json(); if (!r.ok) throw new Error(j.error); // bad_signature · stale_timestamp · nonce_reused · unknown_key · partner_paused · invalid_phone … return j.url; // open it in your iframe within 5 minutes — it works once }
Sign the exact string you send as the body. If your framework re-serialises JSON (adds spaces, reorders keys), sign after that step — or send the string you signed.
<?php // PHP 8 — on YOUR server, never in the browser $keyId = 'pk_your_key_id'; $secret = getenv('O1W_SECRET'); // dashboard → Settings → API key $body = json_encode(['player_id' => $player['id'], 'mobile' => $player['mobile'], 'name' => $player['name'], 'lang' => 'hi', 'game' => 'lobby'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $ts = time(); $nonce = bin2hex(random_bytes(16)); $sig = hash_hmac('sha256', "$ts.$nonce.$body", $secret); // sign the exact bytes you send $ch = curl_init('https://api.only1win.club/api/partner/v1/launch'); curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json', "X-Partner-Key: $keyId", "X-Partner-Ts: $ts", "X-Partner-Nonce: $nonce", "X-Partner-Sig: $sig"]]); $res = json_decode(curl_exec($ch), true); if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) !== 200) throw new Exception($res['error'] ?? 'launch_failed'); echo $res['url']; // open it in your iframe within 5 minutes — it works once
<iframe id="o1w" src="LAUNCH_URL_FROM_YOUR_SERVER" allow="autoplay; microphone; clipboard-write; clipboard-read; web-share" style="border:0;width:100%;height:100%;display:block" title="only1win"></iframe>
Where it may be framed
Add the exact https origin of the page that holds the iframe to the dashboard → Settings → Allowed origins (e.g. https://play.example.com). Your site URL is added for you when your account is made. only1win refuses to be framed anywhere else — the browser blocks it.
What the player sees
- First open: a splash with your logo and “in Partnership with only1win”, then a card — the mobile number (locked, from your launch call), Send OTP, the 6-digit code, a name, the 18+ tick — and the game.
- Every later open: the splash, then the game. No code, no login.
- Inside the frame the player has Home, Players, Lucky and Me — the whole game. Only the account’s security pages (password, 2FA, devices) live at only1win.bet.
Rules of the frame
- Keep
allow="autoplay; microphone; clipboard-write; clipboard-read; web-share": the reel sound, voice chat at the tables, Copy buttons and sharing need it. - Give the frame the whole viewport (or at least 360 × 640 px). The game is built for phones first.
- Do not set
referrerpolicy="no-referrer"on the iframe — the game uses your origin to send you messages. The browser default is fine. - In a native app, use a real browser view (Chrome Custom Tabs / SFSafariViewController) or a WebView that allows microphone and clipboard. Inside a WebView the game knows it is in an app and sends withdrawals to the web — see Withdrawals.
If your page reloads with the same launch URL (a refresh, a restored tab), the game keeps the player’s live session in that tab — you only need a fresh URL when the game sends need_session.
From the game to you
init.window.open or your app’s browser.lobby, global, 1v1, wallet …From you to the game
lang (en / hi) sent before the game is up switches it at once; sent after ready it applies from the player’s next open — for the first open pass lang in the launch call.close.Sample
const O1W = 'https://api.only1win.club'; // the frame's origin const frame = document.getElementById('o1w'); window.addEventListener('message', (e) => { if (e.origin !== O1W || e.data?.ns !== 'o1w') return; // only the game, nobody else const { type, data } = e.data; if (type === 'ready') frame.contentWindow.postMessage({ ns: 'o1w', v: 1, type: 'init', data: { insets: { top: 0, bottom: 0 } } }, O1W); if (type === 'need_session') reloadWithFreshLaunchUrl(); // the 24 h session ended — ask your server for a new launch url if (type === 'open_url') window.open(data.url, '_blank'); // Telegram help, a UPI app — open outside the frame if (type === 'close') hideTheFrame(data.reason); if (type === 'route') console.log('screen', data.screen); // lobby · global · 1v1 · wallet … if (type === 'balance') showBalance(data.inr / 100); // the player's ₹ balance, in paise }); // to the game, when you need to: // frame.contentWindow.postMessage({ ns:'o1w', v:1, type:'visibility', data:{ hidden:true } }, O1W); // your app went to the background // frame.contentWindow.postMessage({ ns:'o1w', v:1, type:'back' }, O1W); // the user pressed Back in your app
- Deposits are never withdrawable; only winnings are (the normal only1win rule).
- A partner player confirms every withdrawal with an SMS code to their mobile number — one more check, because they have no only1win password.
- Withdrawals are done on the web version only. When the game runs in a browser tab on your website, players withdraw inside the frame. Inside an app or WebView the game shows “Withdrawals are done on the web version” with your site URL, where they open the game again and withdraw.
- App-only platform, no website? Leave the site URL empty: players are sent to only1win.bet, where they log in with the same mobile number (they set a password at the first login) and withdraw there.
You never touch player money: deposits go to only1win, withdrawals are paid by only1win. Your dashboard shows your players’ deposits and withdrawals by day, without any bank or wallet detail.
How only1win earns, in one line
On every table the players’ bets make a pool; the winner takes the pool minus a 10 % platform fee. That fee is all only1win earns — and your earnings come out of it. Nothing is charged to you, ever.
Pick a model
Paid to your wallet game by game, the moment each one ends. Withdraw in USDT any time — no hold, no minimum.
Side by side
| Fixed share | Referral | |
|---|---|---|
| You earn | 40 % of only1win’s fee on every game played through your platform — by anyone (60 % stays with only1win) | 20 % of the fee on your own players’ games wherever they play, plus 8 / 5 / 4 / 3 % on their friends’; and 40 % of the fee on games other only1win players play inside your frame |
| Your players see | A clean game — no Refer & Earn | The Promotion tab — they can refer friends themselves |
| Paid | Per game, instantly, to your wallet | Per game, instantly, to your wallet |
| Change it | Any time in Settings — it applies to new players only; a player keeps the model they were created under | |
Good to know
- Switching the model in Settings changes future players only.
- Where a game is played decides who earns. Every game inside your frame counts for you — by a player you brought or an only1win player who already had an account. The same player playing elsewhere does not count for you.
- No fee is ever paid twice: your own Referral players earn you their referral commissions, not a seat share on top.
- Everything is credited the moment a game ends; there is no hold, minimum or review. Withdraw from Payouts any time.
- Save your USDT (TRC20) address in the dashboard → Settings → Payout address — locked with your Google Authenticator code.
- Open Payouts, press Withdraw to USDT, type the amount in ₹ and your Authenticator code.
- The ₹ are converted at only1win’s USDT withdrawal rate (shown on the page), the TRON network fee comes out of the amount, and the transfer leaves only1win’s treasury on-chain. The page tracks it live and shows the transaction id.
- No hold, no review, no schedule — your wallet is yours the moment a game ends.
- One payout at a time: the next one waits the few seconds the first takes to confirm.
- Any amount that converts to at least 1 USDT after the network fee.
- PNG, JPEG or WebP, up to 2 MB; converted to WebP on upload.
- Shown 112 px tall, the width follows — a wide wordmark or a square mark both work; avoid tiny text.
- The background is dark green felt: use a transparent background with a light or coloured mark. A dark logo on a dark box disappears.
- Upload it in the dashboard → Settings → Logo; the preview there shows it on the felt, as players see it.
- Settings → Allowed origins has the exact https origin of every page that frames the game.
- Settings → Site URL is set (or deliberately empty for an app-only platform).
- Settings → Logo uploaded and checked on the felt.
- Your server signs launches with the key id and secret from Settings → API key; the clock is right; a nonce is never reused.
- Your page listens for
need_sessionandopen_url. - Settings → Payout address saved, so you can withdraw your earnings.
- Test with your own mobile number: launch → SMS code → play a ₹1 Global round → see the game in Games and the share in Earnings.
Need an account? Write in the Telegram discussion group — it is free, and a team member sets you up. Already a partner? Open your dashboard.
Launch API
| Status | Error | Meaning |
|---|---|---|
| 401 | bad_signature | The signature does not match the bytes you posted |
| 401 | stale_timestamp | X-Partner-Ts is more than 60 s off |
| 401 | nonce_reused | The same nonce within 10 minutes |
| 401 | unknown_key | No such key id |
| 403 | partner_paused | Your platform is paused |
| 400 | invalid_player_id | Letters, digits, _ . : -, up to 64 |
| 400 | invalid_phone · country_not_supported | The mobile number |
| 409 | mobile_mismatch | This player_id is linked to another number |
Inside the frame
These are shown to the player as a card, with a “Reopen from <your platform>” button that sends you close:
| Card | When |
|---|---|
| This link has expired | The launch URL was older than 5 minutes or used already (and no live session in the tab) |
| Session over | The 24-hour session ended or was replaced by a sign-in elsewhere — you also receive need_session |
| Platform paused | only1win paused your platform |
| Account suspended | The player’s only1win account is suspended |
| Could not connect | The game could not reach only1win within 15 s |