Getting Started
Learn how to integrate Gamingo games into your platform.
1. Get your API credentials
Contact the Gamingo team to create your operator account. You will receive:
API_KEYβ identifies your tenant (sent in headers)API_SECRETβ used to verify HMAC signaturesTENANT_IDβ your unique operator identifier
2. Implement Wallet Endpoints
You must implement 4 HTTP endpoints that Gamingo will call for every bet and win. See the Seamless Wallet section.
3. Embed the Game
Games are embedded via iframe. Create a player session, then load the game URL. See Game Integration.
4. Configure Webhooks (optional)
Subscribe to events like round completions and settlements. See Webhooks.
Authentication
API Key Authentication
All operator API calls must include the X-Api-Key header:
X-Api-Key: your-api-key-hereCreating Player Sessions
Before a player can play, create a session token:
const fetch = require('node-fetch');
const res = await fetch('https://api.gamingo.com/auth/session', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'your-api-key'
},
body: JSON.stringify({
player_id: 'player-123',
metadata: { name: 'John', country: 'BR' }
})
});
const { token, player_id } = await res.json();HMAC Signature Verification
Gamingo signs all wallet callbacks with HMAC-SHA256. Verify the signature:
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', apiSecret)
.update(JSON.stringify(body)).digest('hex');
// Compare with req.headers['x-signature']Seamless Wallet
Wallet Callbacks (Gamingo β Operator)
Gamingo uses the Seamless Wallet protocol. Your platform manages all player balances. When a player bets or wins, Gamingo calls your endpoints synchronously (these are callbacks, not webhooks). Your server must respond with the updated balance and a transaction ID.
Flow Diagram
Player clicks "Bet" in Game
|
Gamingo API -> POST your-server/wallet/bet
|
Your server debits player balance
|
Returns { balance, transaction_id }
|
Game proceeds...
|
Player cashes out (or crashes)
|
Gamingo API -> POST your-server/wallet/win
|
Your server credits player balance
|
Returns { balance, transaction_id }Endpoints You Must Implement
POST /wallet/balance
Called to check player balance before game starts.
// Request from Gamingo
{
"player_id": "ext-player-123",
"currency": "USD"
}
// Your Response
{
"balance": 150.00,
"currency": "USD"
}POST /wallet/bet
Called when player places a bet. Debit the amount from player balance.
// Request from Gamingo
{
"player_id": "ext-player-123",
"amount": 10.00,
"round_id": "uuid-round",
"game": "aviator",
"transaction_id": "uuid-unique-tx",
"currency": "USD"
}
// Your Response (after debiting)
{
"balance": 140.00,
"transaction_id": "your-internal-tx-id"
}POST /wallet/win
Called when player wins (cash out or game end). Credit the amount.
// Request from Gamingo
{
"player_id": "ext-player-123",
"amount": 25.00,
"round_id": "uuid-round",
"game": "aviator",
"transaction_id": "uuid-unique-tx",
"ref_transaction_id": "uuid-original-bet-tx",
"currency": "USD"
}
// Your Response (after crediting)
{
"balance": 165.00,
"transaction_id": "your-internal-tx-id"
}POST /wallet/rollback
Called to reverse a bet (timeout, error). Refund the original amount.
// Request from Gamingo
{
"player_id": "ext-player-123",
"round_id": "uuid-round",
"transaction_id": "uuid-unique-tx",
"ref_transaction_id": "uuid-original-bet-tx"
}
// Your Response
{
"balance": 150.00,
"transaction_id": "your-internal-tx-id"
}Signature Verification
All wallet callbacks include an X-Signature header. Verify it before processing:
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', apiSecret)
.update(JSON.stringify(body)).digest('hex');
// Compare with req.headers['x-signature']Important Notes
- Idempotency: Use
transaction_idto prevent duplicate processing. If you receive the same transaction_id twice, return the same response. - Timeout: Gamingo waits 5 seconds for your response. After that, the bet is rolled back.
- Retries: Failed calls are retried up to 3 times with exponential backoff.
- Signature: All requests include
X-Signatureheader with HMAC-SHA256 of the body. - Free Spins: During Slots free spins, your wallet will NOT receive
/betcalls β only/wincalls for any winnings. Free spins are handled internally by Gamingo at no cost to the player.
Game Integration
Quick Start: Game URL Endpoint
The easiest way to get an iframe URL is the /auth/game-url endpoint β it creates a player session and returns a ready-to-use URL in one call:
// Request
{
"player_id": "your-player-id",
"game": "aviator", // aviator | mines | dice | plinko | hilo | battle | slots | flap
"currency": "USD",
"lang": "en"
}
// Response
{
"url": "https://games.gamingo.com/?game=aviator&tenantId=...&token=...&playerId=...&apiKey=...&apiUrl=...¤cy=USD&lang=en",
"token": "eyJhbG...",
"playerId": "uuid",
"expiresIn": "24h"
}Simply embed the returned url in an iframe:
<iframe src="${gameUrl}" width="100%" height="600" frameborder="0" allow="autoplay"></iframe>Manual Embedding via iframe
Alternatively, create a session first and build the URL manually:
<iframe
src="https://games.gamingo.com/?game=aviator&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
allow="autoplay"
></iframe><iframe
src="https://games.gamingo.com/?game=mines&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe><iframe
src="https://games.gamingo.com/?game=dice&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe><iframe
src="https://games.gamingo.com/?game=plinko&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe><iframe
src="https://games.gamingo.com/?game=hilo&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe><iframe
src="https://games.gamingo.com/?game=battle&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe><iframe
src="https://games.gamingo.com/?game=slots&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe><iframe
src="https://games.gamingo.com/?game=flap&tenantId=YOUR_TENANT_ID&token=PLAYER_TOKEN&playerId=PLAYER_ID&apiKey=YOUR_API_KEY&apiUrl=https://api.gamingo.com&lang=en"
width="100%"
height="600"
frameborder="0"
></iframe>Query Parameters
| Parameter | Required | Description |
|---|---|---|
| game | Yes | "aviator", "mines", "dice", "plinko", "hilo", "battle", "slots", or "flap" |
| tenantId | Yes | Your tenant UUID |
| token | Yes | Player session JWT token |
| playerId | Yes | Player UUID in Gamingo |
| apiKey | Mines only | Your API key |
| apiUrl | Yes | Gamingo API base URL |
| lang | No | "en", "es", or "pt" (default: "en") |
Aviator WebSocket Events
The Aviator game communicates via WebSocket on the /aviator namespace:
round:betting -> { roundId, serverSeedHash, countdown }
round:start -> { roundId }
round:tick -> { roundId, multiplier }
round:crash -> { roundId, crashPoint }
bet:confirmed -> { betId, amount }
cashout:confirmed -> { payout, multiplier }bet -> { roundId, playerId, amount, currency? }
cashout -> { roundId, playerId }Webhooks
Event Notifications
Configure webhook URLs to receive real-time notifications about game events.
Setup
// Create webhook config
{
"url": "https://your-server.com/gamingo-hooks",
"events": ["round.end", "bet.settled"]
}
// Response
{
"id": "webhook-config-uuid",
"url": "https://your-server.com/gamingo-hooks",
"events": ["round.end", "bet.settled"],
"secret": "generated-webhook-secret",
"active": true
}Available Events
| Event | Description |
|---|---|
| round.start | A new game round has started |
| round.end | A round has completed (crashed or finished) |
| bet.placed | A player has placed a bet |
| bet.settled | A bet has been settled (won or lost) |
| cashout | A player has cashed out |
| fraud.alert | A fraud alert has been triggered |
Webhook Payload
{
"event": "round.end",
"timestamp": "2026-03-29T12:00:00.000Z",
"data": {
"roundId": "uuid",
"game": "aviator",
"crashPoint": 2.45,
"totalBets": 5,
"totalWagered": 150.00,
"totalPayout": 95.00
}
}
// Header: X-Webhook-Signature: hmac-sha256-of-bodybet.settled Webhook Payload
{
"event": "bet.settled",
"timestamp": "2026-03-30T12:00:00.000Z",
"data": {
"game": "aviator",
"roundId": "uuid",
"playerId": "uuid",
"currency": "USD",
"won": true,
"amount": 10.00,
"payout": 25.00,
"multiplier": 2.50,
"crashPoint": 3.12
}
}
// Header: X-Webhook-Signature: hmac-sha256-of-bodyRetry Policy
Failed deliveries (non-2xx response or timeout) are retried up to 3 times. Check the webhook logs in your backoffice dashboard.
Callback vs Webhook
Gamingo communicates with your server in two distinct ways. It is important to understand the difference:
Wallet Callbacks
Synchronous HTTP calls FROM Gamingo TO the operator's wallet endpoints. These happen in real-time during gameplay.
- Called every time a player bets, wins, or needs a rollback
- Operator MUST respond with balance + transaction_id
- Gamingo waits up to 5 seconds for your response
- Signed with
X-Signature(HMAC-SHA256)
Event Webhooks
Asynchronous HTTP notifications FROM Gamingo TO the operator's registered URL. Informational events about game results.
- Sent after game events (round end, bet settled, etc.)
- Operator can process at their own pace
- Only needs to respond with
200 OK - Signed with
X-Webhook-Signature(HMAC-SHA256)
Comparison Table
| Feature | Wallet Callback | Event Webhook |
|---|---|---|
| Direction | Gamingo β Operator | Gamingo β Operator |
| Timing | Synchronous (during game) | Asynchronous (after event) |
| Response required | YES (balance + tx_id) | NO (just 200 OK) |
| Contains | player_id, amount, currency, round_id, game, transaction_id | player_id, currency, game, roundId, won, payout, multiplier |
| Retry | 3 retries, 5s timeout | 3 retries, manual retry available |
| Auth | X-Signature (HMAC-SHA256) | X-Webhook-Signature (HMAC-SHA256) |
Provably Fair
All Gamingo games use a provably fair system based on HMAC-SHA256 hash chains. Players can independently verify every round.
How It Works
1. Before round starts: server_seed = random 256-bit value server_seed_hash = SHA256(server_seed) <- shown to player 2. Player provides (or system generates): client_seed = player-chosen value nonce = sequential counter 3. Result calculation: hash = HMAC-SHA256(server_seed, client_seed + ":" + nonce) 4. After round ends: server_seed is revealed Player verifies: SHA256(server_seed) === server_seed_hash
Aviator -- Crash Point Calculation
const crypto = require('crypto');
function verifyCrashPoint(serverSeed, clientSeed, nonce) {
// Step 1: Verify the hash
const hash = crypto.createHash('sha256')
.update(serverSeed).digest('hex');
// Compare with server_seed_hash shown before round
// Step 2: Calculate crash point
const hmac = crypto.createHmac('sha256', serverSeed)
.update(clientSeed + ':' + nonce)
.digest('hex');
const h = parseInt(hmac.slice(0, 13), 16);
const e = Math.pow(2, 52);
// ~3% house edge (h % 33 === 0 -> instant crash)
if (h % 33 === 0) return 1.00;
return Math.max(1, Math.floor((98 * e) / (e - h)) / 100);
}Mines -- Position Calculation
function verifyMinePositions(serverSeed, clientSeed, nonce, mineCount) {
const positions = [];
const available = Array.from({ length: 25 }, (_, i) => i);
for (let i = 0; i < mineCount; i++) {
const hmac = crypto.createHmac('sha256', serverSeed)
.update(clientSeed + ':' + nonce + ':' + i)
.digest('hex');
const idx = parseInt(hmac.slice(0, 8), 16) % available.length;
positions.push(available[idx]);
available.splice(idx, 1);
}
return positions;
}API Reference
Base URL: https://api.gamingo.com
Authentication Endpoints
Game Endpoints
Dice Endpoints
Plinko Endpoints
Hi-Lo Endpoints
Battle Endpoints
Slots Endpoints
Free Spins Mechanic
The Slots game includes a Free Spin feature triggered by Scatter symbols (β):
- Trigger: 3+ Scatter symbols anywhere on the 3x3 grid = 8 free spins (+4 per extra scatter)
- No debit: Free spins don't charge the player β only wins are credited
- Progressive multiplier: Spins 1-3 = 1x, spins 4-6 = 2x, spins 7+ = 3x applied to all wins
- Retrigger: 3+ scatters during free spins = +8 additional spins
{
"roundId": "uuid",
"grid": [["blossom","scatter","coin"],["scatter","gem","orange"],["bamboo","scatter","lantern"]],
"wins": [...],
"totalMultiplier": 0,
"payout": 0,
"won": false,
"freeSpinsAwarded": 8, // 3 scatters β 8 free spins!
"scatterCount": 3,
"serverSeedHash": "...",
"serverSeed": "...",
"clientSeed": "...",
"nonce": 0
}{
"playerId": "uuid",
"originalBet": 10, // the bet amount from the triggering spin
"spinNumber": 1, // which free spin (1-based)
"currency": "USD"
}
// Response:
{
"roundId": "uuid",
"grid": [["gem","coin","lantern"],["coin","coin","orange"],["bamboo","envelope","blossom"]],
"wins": [{ "payline": 1, "symbol": "coin", "count": 3, "multiplier": 5 }],
"totalMultiplier": 5,
"progressiveMultiplier": 1, // 1x for spins 1-3
"payout": 48.50,
"won": true,
"extraFreeSpins": 0 // 0 = no retrigger
}Free Rounds Endpoints
{
"playerId": "player-uuid",
"game": "mines",
"amount": 10,
"count": 5,
"currency": "USD",
"expiresAt": "2026-12-31T23:59:59Z" // optional
}
// Response:
{
"id": "uuid",
"playerId": "player-uuid",
"game": "mines",
"amount": 10,
"currency": "USD",
"remaining": 5,
"total": 5,
"expiresAt": "2026-12-31T23:59:59.000Z",
"createdAt": "2026-03-30T12:00:00.000Z"
}{
"available": {
"id": "uuid",
"amount": 10,
"currency": "USD",
"remaining": 3,
"total": 5
}
}
// When no free rounds available:
{ "available": null }