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

The flow

  1. Your server asks only1win for a launch URLTheir id on your platform + the mobile number, signed with your API key. One call per open.
  2. 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.
  3. 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.
  4. 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

  1. Open partner.only1win.club and sign in with the email and password you were given.
  2. Set a new password (at least 10 characters).
  3. 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

PageWhat it shows
DashboardPlayers, deposits, withdrawals, games, bets, fee, your share — Today · Yesterday · This month · the dates you pick
PlayersEveryone who came from your platform: your player id, masked mobile, model, deposits, withdrawals, bets, won, last seen
Deposits · WithdrawalsYour players’ money in and out, by day — never a bank or wallet detail
Games · EarningsEvery game your players sat at, and what each one earned you
PayoutsYour wallet → USDT TRC20 to your saved address, live tracking
SettingsLogo, site URL, allowed origins, language, revenue model, payout address, API key, dashboard logins
LogEvery change on your account, by whom
TermMeaning
player_idYour 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 URLA one-time address for one player, good for 5 minutes, returned by the Launch API. You open it in your iframe.
Verified playerA player who confirmed the mobile number with an SMS code inside your frame once. Every later launch opens the game at once.
Linked accountSomeone 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 sessionThe 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 modelFixed share or Referral — see Revenue models. The model active when a player is created stays with that player forever.
ShareYour % (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 walletWhere your earnings land, the moment each game ends. Withdraw from it in USDT, any time.
Site URLYour website. Its origin may frame the game, and players in your app are sent there to withdraw.
Allowed originsThe exact https origins that may frame the game (https://play.example.com). Anything else is refused by the browser.
POST/api/partner/v1/launch
https://api.only1win.club

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

X-Partner-Keystringheaderrequired
Your key id — pk_… from the dashboard → Settings → API key.
X-Partner-Tsstringheaderrequired
Unix time in seconds. only1win accepts ±60 s — keep your clock right (NTP).
X-Partner-Noncestringheaderrequired
A random string, up to 64 characters, never reused within 10 minutes.
X-Partner-Sigstringheaderrequired
Hex HMAC-SHA256 with your secret over ts + "." + nonce + "." + rawBody — the exact bytes you post, no re-serialising.

Body

player_idstringrequired
Your user’s id on your platform — letters, digits, _ . : -, up to 64. The link between your user and the only1win player; stable forever.
mobilestringrequired
The user’s mobile number with country code, e.g. +919812345678 (India today).
namestring
Optional display name, up to 20 characters. Shown as the suggestion on the first open.
langstring
Optional — en or hi. The language the game opens in for this player.
gamestring
Optional — lobby (default), global, 1v1, 1v5, 1v10: where the frame opens.

Response

200JSON
{
  "url": "https://api.only1win.club/embed/your-slug#c=…",
  "expires_in": 300,
  "status": "new"
}
urlstring
Open it in your iframe within 5 minutes — it works once. Never cache it, never put it in an email or a link list.
status"new" | "linked"
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

StatusErrorWhy
401bad_signatureThe signature does not match the bytes you posted, or the key is wrong
401stale_timestampX-Partner-Ts is more than 60 s away from only1win’s clock
401nonce_reusedThe same nonce within 10 minutes
401unknown_keyNo such key id (rotated?)
403partner_pausedYour platform is paused — contact only1win
400invalid_player_id · invalid_phone · country_not_supportedThe body
409mobile_mismatchThis player_id is already linked to a different mobile number — the number of a linked player cannot change
launch.mjsJavaScript
// 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.

launch.phpPHP
<?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
play.htmlHTML
<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

ready
The game is up — answer with init.
need_session
The 24-hour session ended, or was replaced by a sign-in on another device: get a fresh launch URL from your server and reload the frame.
open_url{ url }
Open this outside the frame (Telegram help, a UPI app intent) — window.open or your app’s browser.
close{ reason }
The player wants to leave the game: Back on the home screen, or a card they dismissed.
route{ screen }
The screen the player is on — lobby, global, 1v1, wallet …
balance{ inr }
The player’s ₹ balance in paise, whenever it changes.

From you to the game

init{ insets, lang }
The safe-area insets of your app in px. 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.
visibility{ hidden }
Your app went to the background or came back — the game pauses sound and timers accordingly.
back
The user pressed Back in your app — the game goes back one screen, or sends close.

Sample

play.jsJavaScript
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

Fixed share — what could you earn?Three sliders, one number. An estimate — real earnings depend on how much your players actually play.
only1win keeps a 10 % fee on their games — it is split
40 % you60 % only1win
You could earn₹0in a month

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 shareReferral
You earn40 % 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 seeA clean game — no Refer & EarnThe Promotion tab — they can refer friends themselves
PaidPer game, instantly, to your walletPer game, instantly, to your wallet
Change itAny 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.
  1. Save your USDT (TRC20) address in the dashboard → Settings → Payout address — locked with your Google Authenticator code.
  2. Open Payouts, press Withdraw to USDT, type the amount in ₹ and your Authenticator code.
  3. 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.
  • 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_session and open_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

StatusErrorMeaning
401bad_signatureThe signature does not match the bytes you posted
401stale_timestampX-Partner-Ts is more than 60 s off
401nonce_reusedThe same nonce within 10 minutes
401unknown_keyNo such key id
403partner_pausedYour platform is paused
400invalid_player_idLetters, digits, _ . : -, up to 64
400invalid_phone · country_not_supportedThe mobile number
409mobile_mismatchThis 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:

CardWhen
This link has expiredThe launch URL was older than 5 minutes or used already (and no live session in the tab)
Session overThe 24-hour session ended or was replaced by a sign-in elsewhere — you also receive need_session
Platform pausedonly1win paused your platform
Account suspendedThe player’s only1win account is suspended
Could not connectThe game could not reach only1win within 15 s
© only1win · 18+ only · Play responsibly