Розмістіть 500 доказово чесних ігор у своєму казино
Один API-ключ. Безшовний POL-гаманець. Без плати за підключення й абонплати — ми беремо лише 15% revenue share від GGR, який приносять ваші гравці. Не програмуєте? Завантажте наш безкоштовний скрипт казино і запустіться за 5 хвилин.
POST /api/v1/sessions
{
"player_id": "42",
"username": "alice",
"game": "banana-splash"
}
→ { "launch_url": "https://…/embed.php?token=…" }Отримайте ключі
Зареєструйтеся, вкажіть бренд і сайт — API-ключ і секрет створюються миттєво.
Підключіть свій гаманець
Додайте callback URL вашого гаманця (або встановіть безкоштовний скрипт, де він уже є) і запустіть вбудований тест.
Запуститися
Отримайте список ігор через GET /games, запускайте через POST /sessions. Сплатіть рахунок revenue share за щотижня у POL.
Overview
The Polygon Casino Partner API lets you put all of our provably fair games on your own website. It is free: we earn a revenue share of the gross gaming revenue (GGR) your players generate. Players keep their balance on your site — our game server talks to your wallet endpoint (“seamless wallet”) to take bets and pay wins in POL.
- Create a partner account and copy your API key and API secret.
- Implement the wallet callback on your server and save its URL in the panel.
- Call
GET /gamesto list games, thenPOST /sessionsto get alaunch_urland open it in an iframe. - Pay the revenue share invoice each period. Unpaid invoices suspend the API automatically.
Prefer not to code? Download the free casino script from the panel — it implements everything below.
Base URL & authentication
Base URL: https://polygoncasinos.net/api/v1Fallback (no URL rewriting): https://polygoncasinos.net/api/v1/index.php?route=games
Every request must include three headers:
| Header | Value |
|---|---|
X-API-Key | Your public key, e.g. pk_your_api_key |
X-Timestamp | Current unix time in seconds (must be within ±5 minutes) |
X-Signature | hex( HMAC_SHA256( secret, timestamp + "." + raw_body ) ) — for GET requests the body is an empty string |
All responses are JSON: {"ok":true,...} or {"ok":false,"error":"CODE","message":"..."} with a matching HTTP status. Amounts are POL with 8 decimals.
PHP example
function pc_api(string $method, string $route, ?array $body = null) {
$key = 'pk_your_api_key'; $secret = 'sk_your_secret';
$raw = $body === null ? '' : json_encode($body);
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $raw, $secret);
$ch = curl_init('https://polygoncasinos.net/api/v1/' . $route);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $body === null ? null : $raw,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', "X-API-Key: $key", "X-Timestamp: $ts", "X-Signature: $sig"]]);
return json_decode(curl_exec($ch), true);
}
$games = pc_api('GET', 'games');
$s = pc_api('POST', 'sessions', ['player_id' => '42', 'username' => 'alice', 'game' => 'banana-splash', 'return_url' => 'https://yoursite.com/lobby']);
echo '<iframe src="' . $s['launch_url'] . '" allow="fullscreen" style="width:100%;height:760px;border:0"></iframe>';
Node.js example
const crypto = require('crypto');
async function pcApi(method, route, body) {
const raw = body ? JSON.stringify(body) : '';
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac('sha256', process.env.PC_SECRET).update(ts + '.' + raw).digest('hex');
const r = await fetch('https://polygoncasinos.net/api/v1/' + route, { method, body: body ? raw : undefined,
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.PC_KEY, 'X-Timestamp': ts, 'X-Signature': sig } });
return r.json();
}
cURL
TS=$(date +%s); SIG=$(printf '%s.' "$TS" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //') curl -H "X-API-Key: $KEY" -H "X-Timestamp: $TS" -H "X-Signature: $SIG" https://polygoncasinos.net/api/v1/ping
Endpoints
GET /ping
Checks your credentials. Returns your partner id, status, revenue share % and wallet URL.
GET /games
Lists all enabled games. Optional filters: ?category=slots (engine key) or ?group=slots|table|originals.
{"ok":true,"count":350,"categories":[{"key":"slots","label":"Video Slots","icon":"🎰","group":"slots"},…],
"games":[{"slug":"banana-splash","name":"Banana Splash","category":"slots","category_label":"Video Slots","group":"slots",
"theme":"banana","rtp":96.5,"min_bet":0.01,"max_bet":100,"thumbnail":"https://polygoncasinos.net/cover.php?g=banana-splash",
"is_new":false,"is_hot":false,"featured":true,"provably_fair":true}, …]}
Thumbnails are 300×400 SVG images you can hot-link.
GET /games/{slug}
Single game object.
POST /sessions
Creates a game session for one of your players and returns the iframe URL.
| Field | Type | |
|---|---|---|
player_id | string, 1-64 | Your unique player id (letters, numbers, _ - . @ :). Required. |
username | string | Display name shown in the game. Optional. |
game | slug | Game to open. Required for launching. |
return_url | url | Where the “Lobby” button sends the player. Optional. |
lang | string | Game UI language: en, tr, de, fr, es, pt, it, ru, uk, pl, nl, ro, el, sv, az, kk, ar, fa, hi, id, vi, th, ja, ko, zh (default en). Without it the player's country is not used — pass your site's language. |
Returns HTTP 201:
{"ok":true,"token":"9f1c…","launch_url":"https://polygoncasinos.net/embed.php?token=9f1c…&game=banana-splash","expires_at":"2026-10-14 18:00:00Z","player":{"id":"42","internal_id":1834}}
Open launch_url in an iframe (recommended size 100% × 760px, allow="fullscreen"). Sessions last 6 hours and are extended while the player is active.
GET /bets?from=YYYY-MM-DD&to=YYYY-MM-DD&page=1&per_page=100
All rounds played by your players (newest first): id, round_id, player_id, game, amount, payout, multiplier, created_at.
GET /players/{player_id}/bets?limit=50
Latest rounds of one player including provably-fair data (server_seed_hash, client_seed, nonce).
GET /stats?from=YYYY-MM-DD&to=YYYY-MM-DD
{"ok":true,"stats":{"bets":1520,"players":37,"turnover":812.5,"payouts":781.2,"ggr":31.3,"revshare_percent":15,"revshare_amount":4.695},"outstanding":4.695}
GET /invoices
Your revenue share invoices with status open, overdue, paid, zero or waived.
Sportsbook (football, basketball, tennis)
Pre-match and live betting on football (top European leagues, Süper Lig, Champions League, MLS…), basketball (NBA) and tennis (ATP / WTA) with singles and combos (up to 20 selections). Odds come from our own pricing model; stakes and wins use the same seamless wallet as casino games with "game": "sportsbook" and one round_id per coupon (debit when the bet is placed, credit — possibly 0 — when it is settled). Sportsbook GGR (stakes − wins of settled coupons, refunded coupons excluded) is part of your revenue share invoices.
Embedded sportsbook (easiest)
Create a session with "game": "sportsbook" and open its launch_url in an iframe — the complete sportsbook UI (lobby, live, bet slip, my bets) runs inside it:
$s = pc_api('POST', 'sessions', ['player_id' => '42', 'username' => 'alice', 'game' => 'sportsbook', 'return_url' => 'https://yoursite.com/']);
echo '<iframe src="' . $s['launch_url'] . '" style="width:100%;height:900px;border:0"></iframe>';
GET /sports/events?sport=&league=&day=&q=
sport = soccer|basketball|tennis (empty = all), league = league key (e.g. eng.1, tur.1, nba, atp), day = live|today|tomorrow|week (default week), optional q (team search), limit (max 500), tz (minutes, like JavaScript getTimezoneOffset(), for “today/tomorrow”). Returns sport and league counters and the events with all markets. Times are ISO 8601 UTC.
{"ok":true,"count":1,"sports":[{"key":"soccer","name":"Football","icon":"⚽","count":214,"live":9},…],
"leagues":[{"key":"eng.1","name":"Premier League","sport":"soccer","country":"GB-ENG","flag":"🏴","count":30},…],
"events":[{"id":31,"sport":"soccer","league":"eng.1","league_name":"Premier League","home":"Liverpool","away":"Arsenal",
"home_logo":"https://…","away_logo":"https://…","start_at":"2026-10-17T20:45:00Z","status":"pre","status_detail":"",
"clock":null,"period":0,"minute":null,"score":null,"live":false,"suspended":false,"suspend_reason":null,
"markets":[{"key":"1x2","name":"Match Result","line":null,"group":"main","main":true,"suspended":false,
"outcomes":[{"pick":"1","label":"{home}","odds":1.98},{"pick":"X","label":"Draw","odds":3.57},{"pick":"2","label":"{away}","odds":3.49}]},
{"key":"ou","name":"Total Goals","line":2.5,"group":"goals","main":true,"suspended":false,"outcomes":[{"pick":"over","label":"Over","odds":1.76},{"pick":"under","label":"Under","odds":2.07}]},…],
"more":10}]}
A selection is identified by event_id + market key + line + pick. {home} / {away} in labels are placeholders for the team / player names. Status values: pre, live, final, postponed, canceled, suspended. When suspended is true (or a market's suspended) the selection cannot be bet right now.
| Sport | Market keys (picks) |
|---|---|
| Football | 1x2 (1 X 2), dc double chance (1X 12 X2), dnb draw no bet (1 2), ou total goals with line (over under), btts (yes no), eh 3-way handicap −1/+1 (1 X 2), cs correct score (“2-1”…, other). Settled on regular time (90' + stoppage). |
| Basketball | ml moneyline (1 2), spread home line (1 2), total points (over under) — overtime included. |
| Tennis | winner (1 2), sets total sets (over under), sh set handicap ±1.5 from the home player's view (1 2). Retirements are void. |
GET /sports/events/{id}
One event with all markets (same object as above).
POST /sports/bets
| Field | |
|---|---|
player_id, username | Your player (created on first use, like POST /sessions). |
selections | [{"event_id":31,"market":"ou","line":2.5,"pick":"over","odds":1.76}, …] — odds = the price you showed the player. |
stake | POL per coupon (min 0.1, max 500; max net win per coupon 5000 POL). |
type | single (default — one coupon per selection, each with stake) or combo (one accumulator, one selection per event). |
accept | Odds changes: none (default — reject any change), higher (accept better odds), any. |
Returns HTTP 201 {"ok":true,"bets":[BET…],"bet":BET,"balance":12.5}. When prices moved you get HTTP 400 {"ok":false,"error":"ODDS_CHANGED","message":"…","changes":[{"event_id":31,"market":"1x2","line":null,"pick":"1","old":1.88,"odds":1.98}]} — show the new prices and resend. Other errors: EVENT_SUSPENDED, SELECTION_UNAVAILABLE, SAME_EVENT, MIN_STAKE, MAX_STAKE, MAX_PAYOUT, MAX_COMBO_ODDS, INSUFFICIENT_FUNDS, TOO_MANY_SELECTIONS, SPORTS_DISABLED.
BET = {"player_id":"42","id":19,"round_id":"SBccc1…","type":"single","stake":0.3,"total_odds":6.1,"potential_win":1.83,"payout":1.83,
"status":"won","live":true,"created_at":"2026-10-16T09:55:55Z","settled_at":"2026-10-16T11:58:01Z",
"selections":[{"event_id":8,"label":"Liverpool – Club Brugge · Match Result · Liverpool","market":"1x2","market_name":"Match Result",
"line":null,"pick":"1","pick_label":"{home}","odds":6.1,"status":"won","result":"4-2","score":[4,2],"start_at":"2026-10-16T14:00:00Z",
"home":"Liverpool","away":"Club Brugge","sport":"soccer","league_name":"Champions League","event_status":"final"}]}
Coupon status: open, won, lost, void (stake refunded). Void selections (postponed > 48 h, cancelled, abandoned) count as odds 1.00 inside combos.
GET /sports/bets?player_id=&status=open|settled|won|lost|void|all&from=YYYY-MM-DD&to=YYYY-MM-DD&page=1&per_page=50
Coupons of your players (newest first), default last 30 days.
Wallet callback (seamless wallet)
Our server sends POST requests with a JSON body to the wallet URL you configure. Verify every request:
signature = hex( HMAC_SHA256( api_secret, X-PC-Timestamp + "." + raw_body ) ) // compare with X-PC-Signature
Answer within 8 seconds with JSON. Every request carries a unique transaction_id: if you receive the same id again, return the same result without applying it twice (idempotency).
| action | Request fields | Your response |
|---|---|---|
balance | player_id, currency | {"ok":true,"balance":"12.50000000"} |
debit | player_id, amount, transaction_id, round_id, game, currency | Subtract the stake. {"ok":true,"balance":"…"} or {"ok":false,"error":"INSUFFICIENT_FUNDS"} |
credit | player_id, amount, transaction_id, round_id, game, currency | Add the win (amount can be 0 — it closes the round). {"ok":true,"balance":"…"} |
rollback | player_id, amount, transaction_id, ref_transaction_id, round_id, game, currency | Refund the debit ref_transaction_id if you applied it (ignore if unknown). {"ok":true,"balance":"…"} |
Error codes you may return: INSUFFICIENT_FUNDS, PLAYER_NOT_FOUND, INVALID_SIGNATURE, PLAYER_BLOCKED, TRANSACTION_CONFLICT, TRANSACTION_ROLLED_BACK, BAD_AMOUNT, UNSUPPORTED_CURRENCY. Any non-ok debit answer cancels the bet (we then send a rollback for safety). If a rollback arrives for a debit you never saw, remember its id and refuse that debit if it arrives later. Credits that fail are retried automatically in the background.
Minimal PHP wallet
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_PC_TIMESTAMP'] ?? '';
if (!hash_equals(hash_hmac('sha256', $ts . '.' . $raw, SECRET), $_SERVER['HTTP_X_PC_SIGNATURE'] ?? '') || abs(time() - (int)$ts) > 300) {
exit(json_encode(['ok' => false, 'error' => 'INVALID_SIGNATURE']));
}
$r = json_decode($raw, true);
// 1. if transaction_id already processed -> return stored response
// 2. balance / debit (check funds) / credit / rollback inside a DB transaction
// 3. store the transaction_id with the response
echo json_encode(['ok' => true, 'balance' => number_format($newBalance, 8, '.', '')]);
Revenue share & billing
- GGR = stakes − wins of your players (casino rounds + settled sportsbook coupons). Revenue share: 15% of positive GGR (custom rates possible).
- Invoices are created weekly. Negative GGR is carried over to the next period. Amounts under 0.50 POL roll into the next invoice.
- Pay in POL on Polygon to the address shown on each invoice — payments are detected automatically.
- Invoices not paid within 5 days after the period ends become overdue and the API is suspended (error
PAYMENT_REQUIRED, HTTP 402) until paid. Repeated non-payment can lead to cancellation of the partnership.
Error codes
| HTTP | error |
|---|---|
| 401 | UNAUTHORIZED, BAD_TIMESTAMP, BAD_SIGNATURE |
| 402 | PAYMENT_REQUIRED — overdue invoice |
| 403 | ACCOUNT_SUSPENDED, ACCOUNT_CANCELLED, PENDING_APPROVAL, IP_NOT_ALLOWED |
| 400 | Sportsbook: ODDS_CHANGED, EVENT_SUSPENDED, SELECTION_UNAVAILABLE, MAX_PAYOUT, INSUFFICIENT_FUNDS … (see Sportsbook) |
| 404 | NOT_FOUND, GAME_NOT_FOUND, PLAYER_NOT_FOUND, EVENT_NOT_FOUND |
| 409 | WALLET_NOT_CONFIGURED |
| 422 | INVALID_PLAYER, BAD_DATE |
| 429 | RATE_LIMITED (900 requests/minute) |
| 503 | MAINTENANCE, SERVICE_DISABLED |
Provably fair
Every player gets their own server seed (hashed), client seed and nonce. Results use HMAC_SHA256(server_seed, client_seed:nonce:round). Players can rotate seeds and verify any round from inside the game window.