Launch: https://spxgame.games · JSON · Desk currency: TND
Panel: https://spxgame.games/. Save the callback and the secret under API Configuration. This page is the document that button opens.
1. Overview
Two directions. Do not mix them.
| Direction | Who | What | Auth |
|---|---|---|---|
| You → SPXGAME | Launch | Opens a game or Altenar | api_key + secret_key |
| SPXGAME → You | Money | Balance, bet, win, refund | Panel callback URL |
- The player clicks on your site.
- You
POST /api/v2/launch. - You open
data.launch_urlin an iframe. - Your wallet answers
status: 1and the latest balance.
Do not send a balance on launch. With no callback saved, the balance is the player deposit on this account. When a callback is saved, this server asks your site, then records the bet and the win. Home GGR is bets minus wins. The deposit is the solde, not GGR. The same transaction_id is applied once.
2. Authentication
| Field | Required | Use |
|---|---|---|
api_key | Yes | Launch. The key on API Configuration. |
secret_key | Yes, once created | Launch. The secret on API Configuration. It must match. |
callback_url | Yes, on the panel | Your HTTPS wallet. |
player_id | Yes | Your player id. 1–64 characters: letters, digits, _ . : -. |
{
"api_key": "YOUR_API_KEY",
"secret_key": "YOUR_SECRET_KEY"
}
Send both fields in the JSON body. A missing, wrong, or inactive key returns HTTP 401 UNAUTHORIZED.
When a secret is saved, every wallet POST also sends X-Sign: HMAC-SHA256 of the raw body, hex. Catalog and panel calls are a different door. Those use Authorization: Bearer and the same API key. Do not put the bearer token on /api/v2/launch.
3. Wallet — your server
This server POSTs to your callback on every money move. Casino and Altenar use the same four methods.
| Setting | Value |
|---|---|
| URL | Callback URL from API Configuration |
| Method | POST |
| Content-Type | application/json |
| Timeout | 5 seconds |
| Signature | X-Sign when a secret is saved |
Always return the latest balance. The same transaction_id must be idempotent — do not debit twice. status: 1 means success. Do not use HTTP 5xx for insufficient funds. Answer HTTP 200 and status: 0.
3.1 user_balance
{
"method": "user_balance",
"user_id": "12345"
}
{
"status": 1,
"balance": 250.00
}
3.2 Bet — transaction_bet
Sent when a player places a stake. Debit bet from user_id once. A second POST with the same transaction_id must return the same balance and must not debit again.
{
"method": "transaction_bet",
"transaction_id": "trx123",
"round_id": "rnd456",
"user_id": "12345",
"bet": 50.00,
"game": "sweet_bonanza",
"currency": "TND",
"currency_code": "TND"
}
| Field | Required | Description |
|---|---|---|
| method | Yes | transaction_bet |
| transaction_id | Yes | Idempotency key |
| round_id | Yes | Round or coupon |
| user_id | Yes | Your player id |
| bet | Yes | Stake |
| game | No | Game id, or altenar |
Success:
{ "status": 1, "balance": 200.00 }
Insufficient funds:
{ "status": 0, "balance": 10.00 }
3.3 Win — transaction_win
Cashout uses this too. win: 0 may arrive for a lost coupon. Do not reject it. A freespin win can arrive on its own. Accept it and credit the net profit.
{
"method": "transaction_win",
"transaction_id": "trx123-win",
"round_id": "rnd456",
"user_id": "12345",
"win": 100.00,
"game": "sweet_bonanza",
"currency": "TND",
"currency_code": "TND"
}
{ "status": 1, "balance": 300.00 }
3.4 Refund
Credit the player. Use this for a cancelled stake, a voided coupon, or a provider rollback. The amount is refund, not bet. Apply each transaction_id once. A repeated refund must not credit twice.
{
"method": "refund",
"transaction_id": "trx123-rf",
"round_id": "rnd456",
"user_id": "12345",
"refund": 50.00,
"game": "altenar",
"currency": "TND",
"currency_code": "TND"
}
{ "status": 1, "balance": 250.00 }
3.5 Rollback
There is no separate rollback method. A rollback is delivered as method: "refund". Credit refund and return the new balance. Sports void (bet_void) uses this same callback after the original stake was taken. If that stake was never stored, this server does not call you.
| Event | Method you receive | Amount field | Your ledger |
|---|---|---|---|
| Stake | transaction_bet | bet | Debit once |
| Win, cashout, or lost coupon | transaction_win | win (may be 0) | Credit once |
| Refund, void, or rollback | refund | refund | Credit once |
The refund transaction_id is not the bet transaction_id. Keep both. Reply:
{ "status": 1, "balance": 250.00 }
Reject a refund you cannot apply with HTTP 200 and status: 0. HTTP 5xx means this server will retry the credit.
3.6 Wallet replies
| Your reply | Meaning |
|---|---|
HTTP 200 + status: 1 + balance | Accepted |
HTTP 200 + status: 0 + balance | Rejected. A bet is treated as insufficient funds. |
| HTTP 5xx or timeout | Not accepted. A bet is not taken. A win is retried. |
This server does not call account_details.
4. Provider list
GET https://spxgame.games/api/casino/providers
Auth is the API key, not the launch secret. Send Authorization: Bearer YOUR_API_KEY or ?api_key=YOUR_API_KEY. Do not send secret_key on this call.
GET /api/casino/providers?api_key=YOUR_API_KEY
Success:
{
"ok": true,
"flexrix_configured": true,
"items": [
{
"code": "pragmatic",
"label": "Pragmatic Play",
"enabled": true,
"owner_enabled": true,
"games": 120,
"image": "https://...",
"logo": "/admin/logos/pragmatic.png"
}
]
}
| Field | Meaning |
|---|---|
| code | Filter value for the game list provider query. |
| label | Name to show. |
| enabled | This account can launch games from this provider. |
| owner_enabled | The provider is on for the whole desk. |
| games | How many games are stored for this provider. |
| image | One game image, or null. |
| logo | Local logo path, or null when no file is stored. |
A missing or inactive key returns HTTP 401 UNAUTHORIZED.
5. Game list
GET https://spxgame.games/api/casino/games
Same API key as the provider list. Use slug as game_id on launch. 5 Lions is vs243lions.
GET /api/casino/games?api_key=YOUR_API_KEY&provider=pragmatic&search=lion&page=1&per_page=50
| Query | Default | Meaning |
|---|---|---|
| provider | empty | Provider code or label. |
| search | empty | Matches name, slug, or provider. |
| page | 1 | Page number. |
| per_page | 50 | Page size. Maximum 200. |
{
"ok": true,
"page": 1,
"per_page": 50,
"total": 120,
"flexrix_configured": true,
"items": [
{
"slug": "vs243lions",
"uuid": "...",
"name": "5 Lions",
"provider": "Pragmatic Play",
"provider_code": "pragmatic",
"enabled": true,
"active": true,
"provider_enabled": true,
"image": "https://...",
"image_portrait": "https://...",
"image_landscape": "https://...",
"type": "slots",
"technology": "html5",
"is_mobile": true,
"rtp": "96.5",
"has_freespins": false
}
]
}
Launch only a row where enabled, active, and provider_enabled are true. A switched-off game returns HTTP 403 GAME_DISABLED.
6. Launch
POST https://spxgame.games/api/v2/launch
The same handler answers POST /api/launch. Send the game-list slug as game_id. Do not send a mode for casino. Do not send a balance. The player is created on the first launch.
Demo
{
"mode": "fun",
"game_id": "vs243lions",
"currency": "TND",
"language": "en",
"home_url": "https://example.com/lobby"
}
Demo does not call your wallet.
Real money
{
"api_key": "YOUR_API_KEY",
"secret_key": "YOUR_SECRET_KEY",
"username": "player_nick",
"player_id": "12345",
"game_id": "vs243lions",
"currency": "TND",
"language": "en"
}
| Field | Required | Description |
|---|---|---|
| api_key / secret_key | Yes | Account credentials |
| username | Yes | Display name. Defaults to player_id |
| player_id | Yes | Your player id. Created on first launch. |
| game_id | Yes | Catalog slug. 5 Lions is vs243lions |
| currency | Yes | TND |
| language | Yes | en, fr, ar, tr |
| home_url | No | http or https lobby return |
Success:
{
"status": "success",
"data": {
"launch_url": "https://...",
"game_id": "vs243lions",
"player_id": "12345",
"username": "player_nick",
"currency": "TND",
"language": "en"
}
}
<iframe src="LAUNCH_URL" style="width:100%;height:100vh;border:0" allow="fullscreen"></iframe>
Leave mode out. Leave balance out. The player wallet is used. A deposit on that player_id is the casino balance.
7. Sportsbook — Altenar
Same endpoint, same api_key, same secret_key, same player_id. Only mode and game_id change. The wallet stays the same. Do not send a balance.
| Product | mode | game_id | Open |
|---|---|---|---|
| Altenar | altenar or alt | altenar | iframe |
| BetBy | betby or betbey | betby | iframe |
| SportRadar | sportradar, exa, or exasportsbook | exa | iframe |
| Digitain | dijisport, dji, or sportdigi | dji | iframe |
| Betcon | betcon | betcon | iframe |
Horse Racing, EveryMatrix, and classic sports are not on this server. Those modes return HTTP 404 PRODUCT_NOT_ON_THIS_SERVER.
{
"api_key": "YOUR_API_KEY",
"secret_key": "YOUR_SECRET_KEY",
"username": "player_nick",
"player_id": "12345",
"currency": "TND",
"language": "en",
"mode": "altenar",
"game_id": "altenar"
}
Success:
{
"status": "success",
"data": {
"launch_url": "https://alteanr.spxgame.net/launch?token=...&lang=en",
"game_id": "altenar",
"player_id": "12345",
"username": "player_nick",
"currency": "TND",
"language": "en"
}
}
The launch token lasts 2 hours. Request a new launch when it expires. Open data.launch_url. The host is https://alteanr.spxgame.net. player_id in the answer is the id you sent. A deposit on that player is the sports balance.
403 SPORTS_DISABLED means Altenar is switched off for this account.
| What happened | Your method |
|---|---|
| Balance | user_balance |
| Coupon placed | transaction_bet |
| Win or cashout | transaction_win |
| Cancel or void | refund |
Altenar posts to https://spxgame.games/wallet/altenar. BetBy posts to https://spxgame.games/wallet/betbey. SportRadar posts to https://spxgame.games/wallet/bet. Digitain posts to https://spxgame.games/wallet/dji. Betcon posts to https://spxgame.games/wallet/betcon. Those addresses are already set. Do not point them at your site. Your site receives section 3 for these books.
Betcon uses the same player and the same keys. Set mode and game_id to betcon. The launch opens on https://betcon.spxgame.net. The token lasts 10 minutes. 403 SPORTS_DISABLED means Betcon is switched off for this account.
Digitain uses the same player and the same keys. Set mode to dijisport and game_id to dji, and set currency to the player wallet. The launch opens a real session on https://dji.spxgame.net. The home after sign-in is https://dji.spxgame.net/SportsBook/Home. The token lasts 10 minutes. 403 SPORTS_DISABLED means Digitain is switched off for this account.
SportRadar uses the same player and the same keys. Set mode to sportradar and game_id to exa. The launch opens on https://bet.spxgame.net. 403 SPORTS_DISABLED means SportRadar is switched off for this account.
BetBy uses the same player and the same keys. Set mode and game_id to betby, and set currency to the player wallet. The launch opens a real session in that currency. The token lasts 10 minutes, so request a new launch each time the player opens the book. 403 SPORTS_DISABLED means BetBy is switched off for this account.
The panel preview, without a player token, is https://alteanr.spxgame.net/#/overview. A player session must use data.launch_url.
8. Errors
Launch and panel errors:
{ "ok": false, "error_code": "PLAYER_NOT_FOUND", "error_description": "..." }
| HTTP | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Wrong or inactive api_key or secret_key |
| 403 | SPORTS_DISABLED | Altenar is off for this account |
| 403 | GAME_DISABLED | That game is switched off |
| 404 | PRODUCT_NOT_ON_THIS_SERVER | That sportsbook mode is not sold here |
| 400 | validation | game_id, currency, language, or player_id |
| 429 | RATE_LIMITED | More than 300 calls from one address in 60 seconds |
| 502 | UPSTREAM_REJECTED | The game network rejected the launch |
| 502 | DEVELOPER_WALLET | Your callback did not return a balance |
| 504 | DEVELOPER_TIMEOUT | Your wallet did not answer in 5 seconds |
| Wallet field | Meaning |
|---|---|
status: 1 | Success |
status: 0 | Reject, missing field, or insufficient funds |
9. Go-live checklist
- Callback URL is HTTPS and publicly reachable.
user_balance,transaction_bet,transaction_win, andrefund. Rollback and void userefund.- Provider list and game list load with the API key. Launch uses
slugasgame_id. transaction_idis unique and idempotent.- Every reply includes
balance. - Latency is within 5 seconds.
- Insufficient funds is
status: 0, not HTTP 500. - Casino: catalog
game_id(5 Lions isvs243lions), no mode, no balance. - Sports: same player,
modealtenarandgame_idaltenar, no balance. - A lost coupon with
win: 0is accepted. - First
mode=fun, then a 1 TND live test.
GET /health returns { "ok": true } with no key.