ArcadeAPI Documentation
Welcome to the ArcadeAPI documentation. This guide covers everything you need to integrate your iGaming platform with our API — from authentication to game launching, callback handling, and transaction reporting.
ArcadeAPI sits between your platform and our game network. Here's the full data flow:
Your Platform → ArcadeAPI Relay → Game Network Servers
(encrypt with your key) → (re-encrypt for network) → Game URL returned
Game Network Callback (bet data) → ArcadeAPI → Your callback_url
(decrypt network payload) → (re-encrypt with your key) → forwarded to you
This means you never interact with our upstream provider directly. You use your own agency_uid and aes_key that we issue. We transparently relay and re-encrypt everything.
Once your account is approved, you'll receive three values in the Client Portal under API Docs:
| Field | Description |
|---|---|
agency_uid | Your unique agency identifier. Include this in every API request. |
aes_key | 32-character AES-256 encryption key. Keep this secret — never expose it client-side. |
server_url | The ArcadeAPI relay endpoint. Use this as your SERVER_URL in all requests. |
aes_key in client-side code, browser JavaScript, or mobile apps. All encryption must happen server-side.Here's the minimum to get a player into a game:
{
"agency_uid": "your-agency-uid-here",
"aes_key": "your-32-char-aes-key-here",
"server_url": "https://your-arcadeapi-domain.com"
}
// PHP example $payload = json_encode([ 'agency_uid' => 'your-agency-uid', 'member_account' => 'prefix_username', // 4-20 chars, alphanumeric 'game_uid' => '1', 'credit_amount' => '100', 'currency_code' => 'USD', 'language' => 'en', 'timestamp' => (string)(time() * 1000), ]); $encrypted = base64_encode(openssl_encrypt($payload, 'AES-256-ECB', $aesKey, OPENSSL_RAW_DATA)); $response = Http::post("$serverUrl/api/game/v1", [ 'agency_uid' => $agencyUid, 'timestamp' => (string)(time() * 1000), 'payload' => $encrypted, ]);
{
"code": 0,
"msg": "",
"payload": {"game_launch_url": "https://game.provider.com/launch?..."}
}
Every API request uses AES-256-ECB encryption with PKCS7 padding, Base64 encoded. The encryption key is your aes_key.
The request body always has three top-level fields:
| Field | Type | Description |
|---|---|---|
agency_uid | String | Your agency identifier (plain text — not encrypted) |
timestamp | String | Current Unix timestamp in milliseconds |
payload | String | AES-256-ECB encrypted + Base64 encoded JSON string |
// Encrypt $encrypted = base64_encode(openssl_encrypt( $jsonString, 'AES-256-ECB', $aesKey, OPENSSL_RAW_DATA )); // Decrypt $decrypted = openssl_decrypt( base64_decode($encryptedString), 'AES-256-ECB', $aesKey, OPENSSL_RAW_DATA );
// npm install crypto-js const CryptoJS = require('crypto-js'); function encrypt(data, key) { const k = CryptoJS.enc.Utf8.parse(key); return CryptoJS.AES.encrypt(JSON.stringify(data), k, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString(); } function decrypt(cipher, key) { const k = CryptoJS.enc.Utf8.parse(key); return JSON.parse(CryptoJS.AES.decrypt(cipher, k, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8)); }
Use this endpoint to launch a game for a player. In Seamless mode, your platform manages the wallet — our game network will call your callback_url with bet/win data.
| Field | Type | Required | Description |
|---|---|---|---|
agency_uid | String | Required | Your agency ID |
member_account | String | Required | Player username (4–20 chars, a-z 0-9 only, with custom prefix e.g. myop_player1) |
game_uid | String | Required | Game UID from the game list |
credit_amount | String | Required | Player's current balance (Yuan/your currency) |
currency_code | String | Required | e.g. USD, INR, BDT |
language | String | Required | Default: en |
timestamp | String | Required | Unix ms timestamp |
home_url | String | Optional | Back button URL in game |
callback_url | String | Optional | Where the game engine sends bet data |
platform | Int | Optional | 1=Web (default), 2=H5/Mobile |
{
"code": 0,
"msg": "",
"payload": {"game_launch_url": "https://..."}
}
The game network will POST to your callback_url when a player places a bet or wins. Your server must respond within a few seconds with an encrypted payload containing the player's updated balance.
serial_number, it's a retry. Return code: 0 with the latest balance immediately — do not double-deduct.| Field | Type | Description |
|---|---|---|
serial_number | String | Unique bet ID — same number = retry |
member_account | String | Player username |
game_uid | String | Which game |
currency_code | String | Currency |
bet_amount | String | Bet amount (negative = refund) |
win_amount | String | Win amount (negative = refund) |
game_round | String | Game round ID |
timestamp | String | Unix ms |
// Decrypt, adjust balance, return encrypted new balance { "code": 0, // 0=success, 1=failure (server will retry) "msg": "", "payload": "<AES256EncryptionResult>" // of {"credit_amount":"1000","timestamp":"..."} }
In Transfer mode, the game network manages the wallet balance. You deposit/withdraw via the same endpoint — no callback needed.
| Field | Type | Description |
|---|---|---|
credit_amount | String | >0 deposit, <0 withdraw, =0 query balance |
transfer_id | String | Unique transfer reference for each transaction |
| Field | Description |
|---|---|
game_launch_url | Game URL |
transfer_amount | Amount transferred |
before_amount | Balance before transfer |
after_amount | Balance after transfer |
transfer_status | 1=success, 2=failed |
| Field | Type | Description |
|---|---|---|
from_date | Long | Start date (UTC+0, Unix ms) |
to_date | Long | End date (UTC+0, Unix ms) — must be same day as from_date |
page_no | Int | Page number (starts at 1) |
page_size | Int | Records per page (max 5000) |
Returns all available game providers for your account. No payload encryption needed — pass parameters as query string.
| Field | Required | Description |
|---|---|---|
agency_uid | Required | Your agency ID |
code | Required | Provider code (from providers endpoint) |
currency | Optional | Filter by currency |
lang | Optional | Filter by language |
<?php class ArcadeApiClient { private string $serverUrl; private string $agencyUid; private string $aesKey; public function __construct(string $serverUrl, string $agencyUid, string $aesKey) { $this->serverUrl = rtrim($serverUrl, '/'); $this->agencyUid = $agencyUid; $this->aesKey = $aesKey; } private function encrypt(array $data): string { return base64_encode(openssl_encrypt( json_encode($data), 'AES-256-ECB', $this->aesKey, OPENSSL_RAW_DATA )); } private function decrypt(string $payload): ?array { $raw = openssl_decrypt(base64_decode($payload), 'AES-256-ECB', $this->aesKey, OPENSSL_RAW_DATA); return $raw ? json_decode($raw, true) : null; } private function post(string $path, array $innerPayload): array { $body = [ 'agency_uid' => $this->agencyUid, 'timestamp' => (string)(time() * 1000), 'payload' => $this->encrypt($innerPayload), ]; $ch = curl_init($this->serverUrl . $path); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($body), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, ]); $result = curl_exec($ch); curl_close($ch); return json_decode($result, true) ?? []; } public function getGameUrl(string $memberAccount, string $gameUid, float $balance, string $currency = 'USD'): ?string { $result = $this->post('/api/game/v1', [ 'agency_uid' => $this->agencyUid, 'member_account' => $memberAccount, 'game_uid' => $gameUid, 'credit_amount' => (string)$balance, 'currency_code' => $currency, 'language' => 'en', 'timestamp' => (string)(time() * 1000), ]); return $result['payload']['game_launch_url'] ?? null; } // Handle incoming callback from the game network public function handleCallback(array $post, callable $walletUpdater): array { $inner = $this->decrypt($post['payload']); if (!$inner) return ['code' => 1, 'msg' => 'decrypt failed', 'payload' => '']; // $walletUpdater(member, bet, win) => new balance $newBalance = $walletUpdater($inner['member_account'], $inner['bet_amount'], $inner['win_amount']); return [ 'code' => 0, 'msg' => '', 'payload' => $this->encrypt([ 'credit_amount' => (string)$newBalance, 'timestamp' => (string)(time() * 1000), ]), ]; } } // Usage $client = new ArcadeApiClient('https://arcadeapi.yourdomain.com', 'your-uid', 'your-32char-key'); $url = $client->getGameUrl('myop_player1', '1368367', 1000.00, 'USD'); header("Location: $url");
const CryptoJS = require('crypto-js'); const axios = require('axios'); const AES_KEY = 'your-32-character-aes-key-here!!'; const AGENCY_UID = 'your-agency-uid'; const SERVER_URL = 'https://arcadeapi.yourdomain.com'; function encrypt(data) { const key = CryptoJS.enc.Utf8.parse(AES_KEY); return CryptoJS.AES.encrypt(JSON.stringify(data), key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString(); } async function getGameUrl(memberAccount, gameUid, balance, currency = 'USD') { const payload = encrypt({ agency_uid: AGENCY_UID, member_account: memberAccount, game_uid: gameUid, credit_amount: String(balance), currency_code: currency, language: 'en', timestamp: String(Date.now()), }); const { data } = await axios.post(`${SERVER_URL}/api/game/v1`, { agency_uid: AGENCY_UID, timestamp: String(Date.now()), payload, }); return data?.payload?.game_launch_url; }
| Code | Description |
|---|---|
| 0 | Success |
| 10002 | Agency not found |
| 10004 | Payload error (decryption failed) |
| 10005 | System error |
| 10008 | Game does not exist |
| 10011 | Player currencies do not match |
| 10012 | Player name already exists — change player name |
| 10013 | Currency not supported |
| 10014 | PlayerName is incorrect |
| 10015 | Player account must be a-z and 0-9 only |
| 10016 | Account frozen — contact administrator |
| 10017 | Provider does not exist |
| 10018 | Provider does not support this currency |
| 10022 | Incorrect parameters |
| 10023 | Player name must be at least 3 characters |
| 10024 | Wallet mode mismatch |
| 10025 | Insufficient wallet balance |
| 10026 | Transfer failed |
| 10027 | Transfer order already exists |
| 10029 | Start and end dates must be the same day |
| 10030 | Too many requests — retry later |
| 10031 | Only last 60 days can be queried |
| 10033 | home_url cannot contain "?" |
| 10034 | System scheduled maintenance |
| Mode | Endpoint | How it Works | Best For |
|---|---|---|---|
| Seamless | /api/game/v1 |
Your platform holds the wallet. The game network calls your callback_url on each bet/win. You return the new balance. | Operators with existing wallet systems |
| Transfer | /api/game/v2 |
The game network holds a sub-wallet. You deposit/withdraw funds to it. No callback needed. | Simpler integration, new operators |
| Plan | Setup Fee | Game Access | Support |
|---|---|---|---|
| Premium | 1,000 USDT | All Games + Sportsbook | Dedicated developer + Priority <4h |
| Standard | 500 USDT | Casino, Slots, Live, Crash, Fish, Arcade, Lottery | Live chat + 12-24h response |
| Sportsbook | 300 USDT | Sportsbook only | Email + ticket, 24-48h response |
| Priority Provider Channel | +100 USDT | Any plan add-on | Priority provider escalation channel |
Minimum game credit deposit: 500 USDT (game credit wallet, separate from setup fee).
No. ArcadeAPI holds exclusive enterprise-level reseller rights with our game network provider. All communications, transactions, and support go through us — this is how we provide a clean, unified API at a fraction of the direct access cost.
It must be 4–20 characters, using only a-z and 0-9. We recommend a prefix unique to your platform (e.g., myop_player1). Never use the same member_account across different agencies.
Return code: 0 with the latest balance immediately. The same serial_number means the game server is retrying a callback that didn't get a valid response. Do not process the bet again.
Yes. Each game_uid can be opened by any number of players simultaneously with different member_account values.
Go to Security (2FA) in the Client Portal sidebar. Scan the QR code with Google Authenticator or Authy, enter the 6-digit code to confirm, and 2FA will be enabled for all future logins.
USD, INR, BDT, PHP, THB, VND, MYR, IDR, and more. Use the GET /api/game/providers endpoint with a currency filter to see which providers support your currency.