{"openapi":"3.1.0","info":{"title":"AWG Provider API","version":"1.0.0","description":"## เริ่มเชื่อมต่อใน 3 ขั้นตอน\n\n1. สร้าง token ใน **My tokens** ระบุ callback base URL และเก็บ secret ที่แสดงครั้งเดียว\n2. เตรียม wallet callbacks ของคุณ: **verifySession**, **checkBalance**, **settleBets** (ดูแท็บ Wallet callbacks)\n3. เรียก **List games** → สร้าง session ฝั่งระบบของคุณ → เรียก **Launch game** แล้วเปิด `launch_url`\n\n`user_operator_session` คือ session ที่ **backend ของคุณสร้าง** และตรวจสอบผ่าน `verifySession` ไม่ใช่ username หรือรหัสผ่านของ portal หากต้องการทดลองโดยยังไม่มี wallet ให้ใช้ **Games → Demo wallet** ใน portal ได้เลย\n\n## Authentication\n\nเรียกจาก backend ของคุณผ่าน HTTPS โดยส่งทั้งสอง headers:\n\n```http\nAuthorization: Bearer YOUR_OPERATOR_TOKEN\nX-Secret-Key: YOUR_SECRET_KEY\n```\n\nแต่ละ token แยกผู้เล่น ประวัติ และเครดิต pool ของตนเอง ห้ามใส่ credentials ในไฟล์เกมหรือ frontend สาธารณะ ตัวอย่างในเอกสารใช้ค่า placeholder เท่านั้น\n\n## Response และจำนวนเงิน\n\nSuccess ใช้ `status: \"ok\"`; error ใช้ `status: \"error\"`, `code`, `message` จำนวนเงินเป็นหน่วยสกุลเงินจริง (เช่น 10.50 THB) ไม่ใช่สตางค์ เวลาใช้ ISO 8601; round ID และ game code เป็น string\n\n## Service fee และ suspension\n\nPool เป็นเครดิตค่าบริการของ operator แยกจาก wallet ผู้เล่น อัตราเริ่มต้น 0% ค่าบริการ = stake × fee_bps / 10,000 ปัด half-up ตามหน่วยย่อยสกุลเงินต่อ transaction; `100` bps = 1% การชนะไม่เปลี่ยน pool และเดิมพันศูนย์ไม่หักค่าบริการ การ reject ที่ยืนยันแล้วคืนค่าบริการหนึ่งครั้ง ส่วน timeout คงรายการ pending\n\nการ suspend บล็อก launch ใหม่และเดิมพันใหม่ที่มี stake มากกว่า 0 รวมถึงอัตรา 0% แต่ pending settlement, retry และ payout ที่ stake เป็น 0 ยังดำเนินต่อได้\n\n## Optional HMAC signing\n\nใช้ `X-Timestamp` (Unix milliseconds) และ `X-Signature` แทน `X-Secret-Key` โดยยังส่ง Bearer token:\n\n```text\nX-Signature = hex(HMAC-SHA256(secret,\n  timestamp + \"\\n\" + METHOD + \"\\n\" + pathWithQuery + \"\\n\" + hex(SHA256(rawBody))\n))\n```\n\nTimestamp ต้องต่างจาก server น้อยกว่า 5 นาที ใช้ตัวอักษร hex พิมพ์เล็ก และ path/query/body bytes ต้องตรงกับที่ส่งจริง ถ้าส่ง signature ผิดจะไม่ fallback ไปใช้ X-Secret-Key\n"},"servers":[{"url":"https://awg-demo.xyz","description":"AWG backend"}],"tags":[{"name":"Games","description":"ดูเกมและเปิดเล่นผ่าน session ของระบบคุณ"},{"name":"History","description":"ดู settlement และรายละเอียดรอบของ token นี้"},{"name":"Credit pool","description":"ยอดเครดิตค่าบริการของ operator"}],"security":[{"OperatorToken":[],"SecretKey":[]},{"OperatorToken":[],"Timestamp":[],"Signature":[]}],"paths":{"/api/v1/games":{"get":{"tags":["Games"],"operationId":"listGames","summary":"List games","description":"รายการเกมที่ token นี้เข้าถึงได้ ใช้ `game_code` เพื่อ launch เกม ไม่ต้องเดารหัสเอง `total` นับก่อนจำกัด limit; ไม่มี page/offset","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"","enum":["ok"]},"total":{"type":"integer"},"games":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}},"required":["status","total","games"]},"example":{"status":"ok","total":1,"games":[{"game_code":"89","game_id":"lucky-neko","name":"lucky-neko","provider":"pg","provider_label":"PG Soft","status":1,"effective_disabled":false}]}}}},"400":{"description":"Invalid request fields or filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_FILTER","message":"Invalid request fields or filters"}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"500":{"description":"Could not complete request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INTERNAL_ERROR","message":"Could not complete request"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}},"parameters":[{"name":"provider","in":"query","required":false,"description":"","schema":{"type":"string","description":"","default":"pg","enum":["pg"]}},{"name":"status","in":"query","required":false,"description":"1 = available, 7 = disabled. Legacy filters 4/5/6 are accepted but currently return no games.","schema":{"type":"string","description":"","enum":["1","7","4","5","6"]}},{"name":"limit","in":"query","required":false,"description":"","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}]}},"/api/v1/launch":{"post":{"tags":["Games"],"operationId":"launchGame","summary":"Launch game","description":"Creates a launch URL without requiring the portal. Tickets expire in 30 minutes. Legacy claims are one-shot. When browser routing is enabled, the response also contains launch_html and launch_urls: relay the HTML from a reachable origin so the browser can probe and switch domains before navigation. All URLs share one ticket/attempt and can recover the same session for at most five minutes after claim, bounded by ticket expiry. Do not replace the attempt yourself. An expired/used ticket or CONFIG_CHANGED requires a fresh launch.\n\nA plain launch_url still requires its initial host to be reachable. Rotation stops once the session is ready; it never retries a spin. AWG calls the operator wallet verifySession endpoint to resolve the session, username and balance. Never send a player password.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"","enum":["ok"]},"launch_url":{"type":"string","description":"Direct game URL in legacy mode; bootstrap URL when browser routing is enabled. Treat it as a bearer credential.","format":"uri"},"operator_player_session":{"type":"string","description":"Echo of the supplied customer session."},"provider":{"type":"string","description":"","enum":["pg"]},"game_code":{"type":"string","description":""},"language":{"type":"string","description":""},"currency":{"type":"string","description":""},"expires_at":{"type":"string","description":"","format":"date-time"},"launch_html":{"type":"string","description":"Optional when browser routing is enabled. Trusted HTML launch shell for the operator to relay from a reachable origin; contains the short-lived bearer ticket. Do not log or cache. Preserve its CSP and scripts."},"launch_urls":{"type":"array","description":"Optional alternate bootstrap URLs, all sharing the same ticket and attempt. They are not independent sessions.","items":{"type":"string","format":"uri"}}},"required":["status","launch_url","operator_player_session","provider","game_code","language","currency","expires_at"]},"example":{"status":"ok","launch_url":"https://games.example.com/89/index.html?ot=pgl_EXAMPLE&ops=pgl_EXAMPLE","operator_player_session":"customer-session-123","provider":"pg","game_code":"89","language":"en","currency":"THB","expires_at":"2026-10-03T10:30:00Z"}}}},"400":{"description":"Invalid request fields or filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_FILTER","message":"Invalid request fields or filters"}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"403":{"description":"Operator is suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"OPERATOR_SUSPENDED","message":"Operator is suspended"}}}},"409":{"description":"Game unavailable or billing is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"GAME_DISABLED","message":"Game unavailable or billing is not configured"}}}},"500":{"description":"Could not complete request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INTERNAL_ERROR","message":"Could not complete request"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_operator_session":{"type":"string","description":"Session ที่ backend ของลูกค้าสร้างและตรวจสอบได้ใน verifySession; ไม่ใช่ portal login หรือ username.","minLength":1,"maxLength":160,"example":"customer-session-123"},"game_code":{"type":"string","description":"รหัสจาก List games.","example":"89"},"provider":{"type":"string","description":"","enum":["pg"]},"game_id":{"type":"string","description":"Optional slug; when supplied it must match game_code.","example":"lucky-neko"},"language":{"type":"string","description":"Defaults to the token language.","maxLength":16,"example":"en"}},"required":["user_operator_session","game_code","provider"]},"example":{"user_operator_session":"customer-session-123","game_code":"89","provider":"pg","language":"en"}}}}}},"/api/v1/launch/html":{"post":{"tags":["Games"],"operationId":"launchGameHtml","summary":"Launch game (HTML)","description":"Same request, authentication and errors as Launch game, with text/html on success. With browser routing off, the page navigates to /game-launch/<ticket>, which redirects to the game and permits a legacy one-shot claim. With browser routing enabled, the page probes configured game/API/control origins, chooses by latency and weight and retains an iframe while waiting for session-ready. Startup retries reuse one UUIDv4 attempt and recover the same session for at most five minutes after claim, bounded by the 30-minute ticket expiry. Geo/business refusals and stale configuration are terminal. The game URL omits operator_player_session. Relay the returned HTML to avoid depending on one bootstrap host; preserve its CSP and scripts. Do not log or cache the HTML or ticket URLs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_operator_session":{"type":"string","description":"Session ที่ backend ของลูกค้าสร้างและตรวจสอบได้ใน verifySession; ไม่ใช่ portal login หรือ username.","minLength":1,"maxLength":160,"example":"customer-session-123"},"game_code":{"type":"string","description":"รหัสจาก List games.","example":"89"},"provider":{"type":"string","description":"","enum":["pg"]},"game_id":{"type":"string","description":"Optional slug; when supplied it must match game_code.","example":"lucky-neko"},"language":{"type":"string","description":"Defaults to the token language.","maxLength":16,"example":"en"}},"required":["user_operator_session","game_code","provider"]},"example":{"user_operator_session":"customer-session-123","game_code":"89","provider":"pg","language":"en"}}}},"responses":{"200":{"description":"The step-1 launch page. Hand it to the player's browser as is (write it into the page or an iframe, or serve it); the browser runs it and is sent to `https://<api host>/game-launch/<ticket>`, which redirects to the game. Do not parse the page for a game URL: it contains none.","headers":{"Cache-Control":{"description":"Always `no-cache, no-store, must-revalidate`.","schema":{"type":"string"}},"Content-Security-Policy":{"description":"`default-src 'none'` plus the sha256 of the page's one inline script and style; the same policy is also inside the page as a `<meta>`.","schema":{"type":"string"}}},"content":{"text/html":{"schema":{"type":"string"},"example":"<!doctype html>…<a id=\"handoff\" href=\"https://api.example.com/game-launch/pgl1.EXAMPLE?tid=6f1c2a7e-9b3d-4c5e-8f00-1234567890ab\">Continue to the game</a>…"}}},"400":{"description":"Invalid request fields or filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_FILTER","message":"Invalid request fields or filters"}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"403":{"description":"Operator is suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"OPERATOR_SUSPENDED","message":"Operator is suspended"}}}},"409":{"description":"Game unavailable or billing is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"GAME_DISABLED","message":"Game unavailable or billing is not configured"}}}},"500":{"description":"Could not complete request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INTERNAL_ERROR","message":"Could not complete request"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}}}},"/api/v1/history":{"get":{"tags":["History"],"operationId":"listHistory","summary":"List settled spins","description":"อ่านรายการที่ COMMITTED/SETTLED ของ token นี้ เรียงใหม่ไปเก่า ไม่รวม Demo wallet\n\n`count` คือจำนวนที่ส่งกลับ ส่วน `total_matching` คือทั้งหมดที่ตรงตัวกรอง ไม่มี page/offset ใช้ช่วงเวลาและ limit เพื่อจำกัดผลลัพธ์","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"","enum":["ok"]},"count":{"type":"integer"},"total_matching":{"type":"integer"},"spins":{"type":"array","items":{"$ref":"#/components/schemas/Spin"}}},"required":["status","count","total_matching","spins"]},"example":{"status":"ok","count":1,"total_matching":1,"spins":[{"spin_id":101,"main_id":"2073377416000000000","player_name":"player1","game_code":"89","provider":"pg","currency":"THB","bet":10,"win":3,"net":7,"balance_after":993,"spin_ts":"2026-10-03T10:00:00Z"}]}}}},"400":{"description":"Invalid request fields or filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_FILTER","message":"Invalid request fields or filters"}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"500":{"description":"Could not complete request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INTERNAL_ERROR","message":"Could not complete request"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}},"parameters":[{"name":"player_name","in":"query","required":false,"description":"Exact username from your wallet callback.","schema":{"type":"string","description":"","example":"player1"}},{"name":"game_code","in":"query","required":false,"description":"","schema":{"type":"string","description":"","example":"89"}},{"name":"provider","in":"query","required":false,"description":"","schema":{"type":"string","description":"","enum":["pg"]}},{"name":"from","in":"query","required":false,"description":"Inclusive start time.","schema":{"type":"string","description":"","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Exclusive end time.","schema":{"type":"string","description":"","format":"date-time"}},{"name":"limit","in":"query","required":false,"description":"","schema":{"type":"integer","default":50,"minimum":1,"maximum":500}}]}},"/api/v1/history/url":{"get":{"tags":["History"],"operationId":"getRoundUrl","summary":"Get round viewer URL","description":"สร้างลิงก์ดูรายละเอียดรอบ อายุ 10 นาที ผู้ที่มีลิงก์สามารถอ่านรอบนั้นได้จนหมดอายุ เป็น settlement details ไม่ใช่วิดีโอ replay","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"","enum":["ok"]},"main_id":{"type":"string","description":""},"game_code":{"type":"string","description":""},"url":{"type":"string","description":"","format":"uri"},"expires_at":{"type":"string","description":"","format":"date-time"}},"required":["status","main_id","game_code","url","expires_at"]},"example":{"status":"ok","main_id":"2073377416000000000","game_code":"89","url":"https://portal.example.com/history-view?operator=EXAMPLE&main_id=2073377416000000000&expires=1791022200&signature=EXAMPLE","expires_at":"2026-10-03T10:10:00Z"}}}},"400":{"description":"Invalid request fields or filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_FILTER","message":"Invalid request fields or filters"}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"404":{"description":"Round not found for this token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"SPIN_NOT_FOUND","message":"Round not found for this token"}}}},"500":{"description":"Could not complete request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INTERNAL_ERROR","message":"Could not complete request"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}},"parameters":[{"name":"main_id","in":"query","required":true,"description":"Round ID from history.","schema":{"type":"string","description":"","example":"2073377416000000000"}},{"name":"game_code","in":"query","required":false,"description":"Optional matching game code.","schema":{"type":"string","description":"","example":"89"}}]}},"/api/v1/pool":{"get":{"tags":["Credit pool"],"operationId":"getPool","summary":"Get service-fee pool","description":"ยอดเครดิตค่าบริการ ไม่ใช่ยอดผู้เล่น `fee_bps` = basis points (100 = 1%) อัตรา 0% ไม่ต้องมีเครดิต pool; `null` หมายถึงยังไม่ได้กำหนดอัตรา\n\nการเติม pool ดำเนินการโดย provider administrator หลังตรวจสอบการชำระเงิน ไม่มี public top-up API สำหรับ operator","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"","enum":["ok"]},"pool_balance":{"type":"number","description":""},"currency":{"type":"string","description":""},"last_updated":{"type":"string","description":"","format":"date-time"},"billing":{"type":"string","description":"","enum":["turnover_fee"]},"fee_bps":{"type":["integer","null"],"minimum":0,"maximum":10000}},"required":["status","pool_balance","currency","last_updated","billing","fee_bps"]},"example":{"status":"ok","pool_balance":1000,"currency":"THB","last_updated":"2026-10-03T10:00:00Z","billing":"turnover_fee","fee_bps":100}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}}}},"/external-game-launcher/api/v1/GetLaunchURLHTML":{"post":{"tags":["Games"],"operationId":"getLaunchUrlHtml","summary":"GetLaunchURLHTML (PG SOFT-compatible launch)","description":"For integrations built on the PG SOFT Seamless **HTML Scheme** game launch. Same launch as **Launch game (HTML)**: the answer is the step-1 HTML page. `trace_id` (a GUID) is required on the query string; it appears on the page and in the player's error screen for support. Authentication: `operator_token` is your AWG token (`op_…`); send its secret as `secret_key` in the form, or use the usual `X-Secret-Key` / `X-Timestamp` + `X-Signature` headers (the signature covers this exact URL and form body). `extra_args` is one URL-encoded query string: `btt` (must be `1`), `ops` (your player session, sent back to you in `verifySession`, 1..160 bytes), optional `l` (language). `te`, `ri`, `op`, `f`, `iwk`, `oc` are accepted and ignored. Errors use the JSON error shape of **Launch game**.","parameters":[{"name":"trace_id","in":"query","required":true,"description":"A GUID for this request.","schema":{"type":"string","format":"uuid"},"example":"6f1c2a7e-9b3d-4c5e-8f00-1234567890ab"}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"operator_token":{"type":"string","description":"Your AWG token (`op_…`)."},"secret_key":{"type":"string","description":"The token's secret. Optional when sent as the `X-Secret-Key` header or with HMAC headers."},"path":{"type":"string","description":"`/<game_code>/index.html`.","example":"/89/index.html"},"extra_args":{"type":"string","description":"One URL-encoded query string: `btt=1&ops=<player session>&l=<language>`.","maxLength":500,"example":"btt=1&ops=customer-session-123&l=en"},"url_type":{"type":"string","enum":["game-entry"]},"client_ip":{"type":"string","description":"The player's IP address.","example":"203.0.113.7"}},"required":["operator_token","path","extra_args","url_type","client_ip"]},"example":{"operator_token":"op_EXAMPLE","secret_key":"sk_EXAMPLE","path":"/89/index.html","extra_args":"btt=1&ops=customer-session-123&l=en","url_type":"game-entry","client_ip":"203.0.113.7"}}}},"responses":{"200":{"description":"The step-1 launch page. Hand it to the player's browser as is (write it into the page or an iframe, or serve it); the browser runs it and is sent to `https://<api host>/game-launch/<ticket>`, which redirects to the game. Do not parse the page for a game URL: it contains none.","headers":{"Cache-Control":{"description":"Always `no-cache, no-store, must-revalidate`.","schema":{"type":"string"}},"Content-Security-Policy":{"description":"`default-src 'none'` plus the sha256 of the page's one inline script and style; the same policy is also inside the page as a `<meta>`.","schema":{"type":"string"}}},"content":{"text/html":{"schema":{"type":"string"},"example":"<!doctype html>…<a id=\"handoff\" href=\"https://api.example.com/game-launch/pgl1.EXAMPLE?tid=6f1c2a7e-9b3d-4c5e-8f00-1234567890ab\">Continue to the game</a>…"}}},"400":{"description":"Invalid trace_id, form or launch fields (`INVALID_TRACE_ID`, `INVALID_FORM`, `INVALID_URL_TYPE`, `INVALID_PATH`, `INVALID_CLIENT_IP`, `INVALID_EXTRA_ARGS`, `MISSING_FIELDS`, `INVALID_BET_TYPE`, then the codes of Launch game)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TRACE_ID","message":"trace_id must be a GUID on the query string"}}}},"401":{"description":"Missing or invalid token, secret or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INVALID_TOKEN","message":"Missing or invalid token, secret or signature"}}}},"403":{"description":"Operator is suspended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"OPERATOR_SUSPENDED","message":"Operator is suspended"}}}},"409":{"description":"Game unavailable or billing is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"GAME_DISABLED","message":"Game unavailable or billing is not configured"}}}},"500":{"description":"Could not complete request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"INTERNAL_ERROR","message":"Could not complete request"}}}},"503":{"description":"Operator credentials or configuration unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"status":"error","code":"TOKEN_UNAVAILABLE","message":"Operator credentials or configuration unavailable"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"status":{"type":"string","description":"","enum":["error"]},"code":{"type":"string","description":""},"message":{"type":"string","description":""},"missing":{"type":"array","items":{"type":"string","description":""}}},"required":["status","code","message"]},"Game":{"type":"object","properties":{"game_code":{"type":"string","description":"Use this string when launching.","example":"89"},"game_id":{"type":"string","description":"Game slug.","example":"lucky-neko"},"name":{"type":"string","description":"","example":"lucky-neko"},"provider":{"type":"string","description":"","enum":["pg"]},"provider_label":{"type":"string","description":"","example":"PG Soft"},"status":{"type":"integer","enum":[1,7],"description":"1 available, 7 disabled"},"effective_disabled":{"type":"boolean"}},"required":["game_code","game_id","name","provider","provider_label","status","effective_disabled"]},"Spin":{"type":"object","properties":{"spin_id":{"type":"integer","description":"Settlement row ID."},"main_id":{"type":"string","description":"Round identifier; keep as a string.","example":"2073377416000000000"},"player_name":{"type":"string","description":"","example":"player1"},"game_code":{"type":"string","description":"","example":"89"},"provider":{"type":"string","description":"","enum":["pg"]},"currency":{"type":"string","description":"","example":"THB"},"bet":{"type":"number","description":""},"win":{"type":"number","description":""},"net":{"type":"number","description":"Bet minus win; can be negative."},"balance_after":{"type":"number","description":""},"spin_ts":{"type":"string","description":"","format":"date-time"}},"required":["spin_id","main_id","player_name","game_code","provider","currency","bet","win","net","balance_after","spin_ts"]}},"securitySchemes":{"OperatorToken":{"type":"http","scheme":"bearer","description":"Operator token from My tokens. Required with either SecretKey or both HMAC headers."},"SecretKey":{"type":"apiKey","in":"header","name":"X-Secret-Key","description":"Secret shown once when creating or rotating the token."},"Timestamp":{"type":"apiKey","in":"header","name":"X-Timestamp","description":"Optional HMAC authentication: current Unix milliseconds."},"Signature":{"type":"apiKey","in":"header","name":"X-Signature","description":"Optional HMAC authentication: lowercase hex signature; see Authentication guide."}}}}