MangoPlay Partner Streaming API (1.0.0)

Download OpenAPI specification:Download

For partners who show MangoPlay live tables inside their own product.

Request base url: https://api-agg.mangoplay.com/

There are two pieces and you need both:

  1. GET /api/v1/open/partner/rooms — the rooms you may show, each with a ready-to-play signed stream URL. The links expire, so this is a call you repeat, not one you make once at startup.
  2. A WebSocket connection that pushes round events — round opened, betting closed, result, round cancelled, room under maintenance.

This API carries no money and no players. It cannot read or write a wallet and has no overlap with the seamless wallet API an operator integration uses.

Credentials

MangoPlay issues you a PartnerCode and a PartnerSecret. Send both as HTTP headers on every REST call, and in the handshake on the WebSocket.

Every failure answers the same way — 404 with {"code": 4040, "message": "Partner not found."} — whether the code is unknown, the secret is wrong, or the account is suspended. That is deliberate: a different answer per case would let anyone probe which codes exist. Our side logs the real reason, so if you are stuck, contact us and we can tell you which one it was.

Stream URLs expire

Each link is signed and valid for streamTtlSec seconds (300 today). stream.expire is the exact epoch second it dies, so you can schedule a refresh instead of parsing our query string. Call /rooms again before then and swap the URL in your player. An expired link is rejected by the CDN, not renewed.

A room with no stream configured is still listed, just without the stream field — that says the room exists but has no video yet, which is a different problem from the room not being there at all.

Connecting the WebSocket

Socket.IO, WebSocket transport only:

import { io } from 'socket.io-client'

const socket = io('wss://ws.mangoplay.com/partner', {
  transports: ['websocket'],
  auth: { partnerCode: 'YOURCODE', secret: 'your-secret' },
})

socket.on('partner_event', (e) => {
  switch (e.event) {
    case 'partner.round.opened':         /* start your countdown */ break
    case 'partner.round.betting_closed': /* close your bet UI */    break
    case 'partner.round.result':         /* show the result */      break
    case 'partner.round.cancelled':      /* withdraw the round */   break
    case 'partner.room.maintenance':     /* add or remove room */   break
  }
})

If your client cannot set handshake auth, ?partnerCode=...&secret=... on the URL works too. A bad credential fails the connection with UNAUTHORIZED — again without saying which half was wrong.

Every event is delivered under two names. Pick one; listening to both counts everything twice.

Channel Use it when
the event's own name, e.g. partner.round.opened you want one handler per kind
partner_event you want one handler for everything, switching on event

Choosing which rooms you get

On connect you are subscribed to every room you have access to, including rooms we add later. To narrow it:

socket.emit('subscribe', { roomCodes: ['BC-A', 'HL-B'] }, (ack) => {
  // ack.rooms = the rooms you are now on
})
socket.emit('unsubscribe', { roomCodes: ['BC-A'] })
socket.emit('subscribe_all')   // back to everything you may see

Rooms you have no access to are dropped from the list silently, and the ack tells you what actually took effect. socket.emit('ping') answers pong with a timestamp if you want a liveness check of your own on top of Socket.IO's.

server_shutdown means we are restarting: reconnect rather than waiting for a timeout. Socket.IO's own reconnect handles this if you leave it enabled.

Two things to design for

Closing bets is a time, not only an event. round.opened carries bettingEndTime, so you can count down locally from the moment the round starts. We also send round.betting_closed when that time arrives — or earlier, if the dealer closes the round early — but treat it as a convenience. If it arrives late or not at all because of a restart or a network blip, your countdown is still correct.

Events can repeat. On our side a duplicate is possible where a lost event is not, so we chose duplicates. De-duplicate on roundNo together with event.

Betting holes

Every bet in a MangoPlay game sits on a hole — one betting slot on the table. These are the keys your UI renders, and the same keys appear in player bet records on the operator side, so labelling them the way we do keeps the two readable together.

The tables below are generated from the live game client, so they are the holes a player can actually bet today, not every key our result engine can produce. Thai is the wording shown in our own client; English is our own client's wording too, so a player moving between your product and ours sees the same name for the same slot.

A few notes before you build from this:

  • game is the value you receive in /rooms and in every event, so you can key your hole table off it directly.
  • Hole keys are stable. They are what settlement is calculated from on our side, so we do not rename them; new holes are added, old ones are not repurposed.
  • Some keys contain a dot — KHUD_1.1 in Roll a Dice and Belangkai. Keep them as-is; do not normalise to an underscore, or you will not match our records.
  • KHUD_1 to KHUD_4 have no translation yet in either language file, so they are shown here as —. Use "ขุด 1" … "ขุด 4" until we fill them in; we will update this page when we do.
  • Hilo has no HOLE_1_HIGH or HOLE_2_HIGH slot — those combinations exist in the result engine but are not offered as bets.

Baccarat

game = Baccarat — 10 holes

Hole ไทย English
ANY_PAIR คู่ใดก็ได้ Any Pair
BANKER เจ้ามือ Banker
BANKER_BONUS เจ้ามือโบนัส Banker Bonus
BANKER_PAIR เจ้ามือคู่ Banker Pair
DRAW เสมอ Draw
LUCKY6 ลัคกี้ซิกซ์ Lucky 6
PERFECT_PAIR ไพ่คู่เพอร์เฟค Perfect Pair
PLAYER ผู้เล่น Player
PLAYER_BONUS ผู้เล่นโบนัส Player Bonus
PLAYER_PAIR ผู้เล่นคู่ Player Pair

Dragon Tiger

game = TigerDragon — 12 holes

Hole ไทย English
DRAGON มังกร Dragon
DRAGON_BIG มังกรใหญ่ Dragon Big
DRAGON_EVEN มังกรคู่ Dragon Even
DRAGON_ODD มังกรคี่ Dragon Odd
DRAGON_SMALL มังกรเล็ก Dragon Small
DRAW เสมอ Draw
DRAW_PERFECT ไพ่เสมอเหมือน Perfect Draw
TIGER เสือ Tiger
TIGER_BIG เสือใหญ่ Tiger Big
TIGER_EVEN เสือคู่ Tiger Even
TIGER_ODD เสือคี่ Tiger Odd
TIGER_SMALL เสือเล็ก Tiger Small

Hilo

game = Hilo — 36 holes

หลุมเดี่ยว · Single holes

Hole ไทย English
HOLE_1 หลุม 1 Hole 1
HOLE_2 หลุม 2 Hole 2
HOLE_3 หลุม 3 Hole 3
HOLE_4 หลุม 4 Hole 4
HOLE_5 หลุม 5 Hole 5
HOLE_6 หลุม 6 Hole 6

หลุม + ต่ำ · Hole with low

Hole ไทย English
HOLE_1_LOW หลุม 1, ต่ำ Hole 1, Low
HOLE_2_LOW หลุม 2, ต่ำ Hole 2, Low
HOLE_3_LOW หลุม 3, ต่ำ Hole 3, Low
HOLE_4_LOW หลุม 4, ต่ำ Hole 4, Low
HOLE_5_LOW หลุม 5, ต่ำ Hole 5, Low
HOLE_6_LOW หลุม 6, ต่ำ Hole 6, Low

หลุม + สูง · Hole with high

Hole ไทย English
HOLE_3_HIGH หลุม 3, สูง Hole 3, High
HOLE_4_HIGH หลุม 4, สูง Hole 4, High
HOLE_5_HIGH หลุม 5, สูง Hole 5, High
HOLE_6_HIGH หลุม 6, สูง Hole 6, High

คู่หลุม · Pairs

Hole ไทย English
HOLE_1_2 หลุม 1, 2 Hole 1, 2
HOLE_1_3 หลุม 1, 3 Hole 1, 3
HOLE_1_5 หลุม 1, 5 Hole 1, 5
HOLE_1_6 หลุม 1, 6 Hole 1, 6
HOLE_2_3 หลุม 2, 3 Hole 2, 3
HOLE_2_4 หลุม 2, 4 Hole 2, 4
HOLE_3_4 หลุม 3, 4 Hole 3, 4
HOLE_3_5 หลุม 3, 5 Hole 3, 5
HOLE_3_6 หลุม 3, 6 Hole 3, 6
HOLE_4_1 หลุม 4, 1 Hole 4, 1
HOLE_4_5 หลุม 4, 5 Hole 4, 5
HOLE_5_2 หลุม 5, 2 Hole 5, 2
HOLE_5_6 หลุม 5, 6 Hole 5, 6
HOLE_6_2 หลุม 6, 2 Hole 6, 2
HOLE_6_4 หลุม 6, 4 Hole 6, 4

สามหลุม · Triples

Hole ไทย English
HOLE_1_2_3 หลุม 1, 2, 3 Hole 1, 2, 3
HOLE_4_5_6 หลุม 4, 5, 6 Hole 4, 5, 6

สูง / ต่ำ / ไฮโล · High, low, hilo

Hole ไทย English
HOLE_11_HILO หลุม 11, ไฮโล Hole 11, Hilo
HOLE_HIGH หลุม สูง Hole High
HOLE_LOW หลุม ต่ำ Hole Low

Sicbo

game = Sicbo — 52 holes

หลุมเดี่ยว · Single numbers

Hole ไทย English
HOLE_1 หลุม 1 Hole 1
HOLE_2 หลุม 2 Hole 2
HOLE_3 หลุม 3 Hole 3
HOLE_4 หลุม 4 Hole 4
HOLE_5 หลุม 5 Hole 5
HOLE_6 หลุม 6 Hole 6

คู่ผสม · Number pairs

Hole ไทย English
HOLE_1_2 หลุม 1, 2 Hole 1, 2
HOLE_1_3 หลุม 1, 3 Hole 1, 3
HOLE_1_4 หลุม 1, 4 Hole 1, 4
HOLE_1_5 หลุม 1, 5 Hole 1, 5
HOLE_1_6 หลุม 1, 6 Hole 1, 6
HOLE_2_3 หลุม 2, 3 Hole 2, 3
HOLE_2_4 หลุม 2, 4 Hole 2, 4
HOLE_2_5 หลุม 2, 5 Hole 2, 5
HOLE_2_6 หลุม 2, 6 Hole 2, 6
HOLE_3_4 หลุม 3, 4 Hole 3, 4
HOLE_3_5 หลุม 3, 5 Hole 3, 5
HOLE_3_6 หลุม 3, 6 Hole 3, 6
HOLE_4_5 หลุม 4, 5 Hole 4, 5
HOLE_4_6 หลุม 4, 6 Hole 4, 6
HOLE_5_6 หลุม 5, 6 Hole 5, 6

เด้งเจาะจง · Specific doubles

Hole ไทย English
HOLE_1_1 หลุม 1, 1 Hole 1, 1
HOLE_2_2 หลุม 2, 2 Hole 2, 2
HOLE_3_3 หลุม 3, 3 Hole 3, 3
HOLE_4_4 หลุม 4, 4 Hole 4, 4
HOLE_5_5 หลุม 5, 5 Hole 5, 5
HOLE_6_6 หลุม 6, 6 Hole 6, 6

ตองเจาะจง · Specific triples

Hole ไทย English
HOLE_1_1_1 หลุม 1, 1, 1 Hole 1, 1, 1
HOLE_2_2_2 หลุม 2, 2, 2 Hole 2, 2, 2
HOLE_3_3_3 หลุม 3, 3, 3 Hole 3, 3, 3
HOLE_4_4_4 หลุม 4, 4, 4 Hole 4, 4, 4
HOLE_5_5_5 หลุม 5, 5, 5 Hole 5, 5, 5
HOLE_6_6_6 หลุม 6, 6, 6 Hole 6, 6, 6

แต้มรวม · Totals

Hole ไทย English
HOLE_SUM_4 หลุมรวม 4 Hole Sum 4
HOLE_SUM_5 หลุมรวม 5 Hole Sum 5
HOLE_SUM_6 หลุมรวม 6 Hole Sum 6
HOLE_SUM_7 หลุมรวม 7 Hole Sum 7
HOLE_SUM_8 หลุมรวม 8 Hole Sum 8
HOLE_SUM_9 หลุมรวม 9 Hole Sum 9
HOLE_SUM_10 หลุมรวม 10 Hole Sum 10
HOLE_SUM_11 หลุมรวม 11 Hole Sum 11
HOLE_SUM_12 หลุมรวม 12 Hole Sum 12
HOLE_SUM_13 หลุมรวม 13 Hole Sum 13
HOLE_SUM_14 หลุมรวม 14 Hole Sum 14
HOLE_SUM_15 หลุมรวม 15 Hole Sum 15
HOLE_SUM_16 หลุมรวม 16 Hole Sum 16
HOLE_SUM_17 หลุมรวม 17 Hole Sum 17

สูง / ต่ำ / คู่ / คี่ / ตอง · High, low, odd, even, any triple

Hole ไทย English
HOLE_EVEN หลุม คู่ Hole Even
HOLE_HIGH หลุม สูง Hole High
HOLE_LOW หลุม ต่ำ Hole Low
HOLE_ODD หลุม คี่ Hole Odd
HOLE_TONG หลุม ตอง Hole Tong

Roll a Dice

game = RollADice — 42 holes

เต็ง · Single face

Hole ไทย English
TENG1_1 เต็ง 1 Teng 1
TENG1_2 เต็ง 2 Teng 2
TENG1_3 เต็ง 3 Teng 3
TENG1_4 เต็ง 4 Teng 4

อาหาร · Three faces

Hole ไทย English
ARHAL_123 อาหาร 1, 2, 3 Arhal 1, 2, 3
ARHAL_124 อาหาร 1, 2, 4 Arhal 1, 2, 4
ARHAL_134 อาหาร 1, 3, 4 Arhal 1, 3, 4
ARHAL_234 อาหาร 2, 3, 4 Arhal 2, 3, 4

ขุด · Khud

Hole ไทย English
KHUD_1 — —
KHUD_1.1 ขุด 1 Khud 1
KHUD_1.2 ขุด 1, (2) Khud 1, (2)
KHUD_1.3 ขุด 1, (3) Khud 1, (3)
KHUD_2 — —
KHUD_2.1 ขุด 2 Khud 2
KHUD_2.2 ขุด 2, (3) Khud 2, (3)
KHUD_2.3 ขุด 2, (1) Khud 2, (1)
KHUD_3 — —
KHUD_3.1 ขุด 3 Khud 3
KHUD_3.2 ขุด 3, (4) Khud 3, (4)
KHUD_3.3 ขุด 3, (2) Khud 3, (2)
KHUD_4 — —
KHUD_4.1 ขุด 4 Khud 4
KHUD_4.2 ขุด 4, (1) Khud 4, (1)
KHUD_4.3 ขุด 4, (3) Khud 4, (3)

กั๊ก · Kuk

Hole ไทย English
KUK_12 กั๊ก 1, 2 Kuk 1, 2
KUK_13 กั๊ก 1, 3 Kuk 1, 3
KUK_14 กั๊ก 1, 4 Kuk 1, 4
KUK_23 กั๊ก 2, 3 Kuk 2, 3
KUK_24 กั๊ก 2, 4 Kuk 2, 4
KUK_43 กั๊ก 4, 3 Kuk 4, 3

เลี่ยม · Liam

Hole ไทย English
LIUM_12 เลี่ยม 1, 2 Lium 1, 2
LIUM_13 เลี่ยม 1, 3 Lium 1, 3
LIUM_14 เลี่ยม 1, 4 Lium 1, 4
LIUM_21 เลี่ยม 2, 1 Lium 2, 1
LIUM_23 เลี่ยม 2, 3 Lium 2, 3
LIUM_24 เลี่ยม 2, 4 Lium 2, 4
LIUM_31 เลี่ยม 3, 1 Lium 3, 1
LIUM_32 เลี่ยม 3, 2 Lium 3, 2
LIUM_34 เลี่ยม 3, 4 Lium 3, 4
LIUM_41 เลี่ยม 4, 1 Lium 4, 1
LIUM_42 เลี่ยม 4, 2 Lium 4, 2
LIUM_43 เลี่ยม 4, 3 Lium 4, 3

Belangkai

game = Balangkai — 42 holes

เต็ง · Single face

Hole ไทย English
TANG_1 เต็ง 1 Tang 1
TANG_2 เต็ง 2 Tang 2
TANG_3 เต็ง 3 Tang 3
TANG_4 เต็ง 4 Tang 4

อาหาร · Three faces

Hole ไทย English
ARHAL_123 อาหาร 1, 2, 3 Arhal 1, 2, 3
ARHAL_124 อาหาร 1, 2, 4 Arhal 1, 2, 4
ARHAL_134 อาหาร 1, 3, 4 Arhal 1, 3, 4
ARHAL_234 อาหาร 2, 3, 4 Arhal 2, 3, 4

ขุด · Khud

Hole ไทย English
KHUD_1 — —
KHUD_1.1 ขุด 1 Khud 1
KHUD_1.2 ขุด 1, (2) Khud 1, (2)
KHUD_1.3 ขุด 1, (3) Khud 1, (3)
KHUD_2 — —
KHUD_2.1 ขุด 2 Khud 2
KHUD_2.2 ขุด 2, (3) Khud 2, (3)
KHUD_2.3 ขุด 2, (1) Khud 2, (1)
KHUD_3 — —
KHUD_3.1 ขุด 3 Khud 3
KHUD_3.2 ขุด 3, (4) Khud 3, (4)
KHUD_3.3 ขุด 3, (2) Khud 3, (2)
KHUD_4 — —
KHUD_4.1 ขุด 4 Khud 4
KHUD_4.2 ขุด 4, (1) Khud 4, (1)
KHUD_4.3 ขุด 4, (3) Khud 4, (3)

กั๊ก · Kuk

Hole ไทย English
KUK_13 กั๊ก 1, 3 Kuk 1, 3
KUK_14 กั๊ก 1, 4 Kuk 1, 4
KUK_21 กั๊ก 2, 1 Kuk 2, 1
KUK_23 กั๊ก 2, 3 Kuk 2, 3
KUK_24 กั๊ก 2, 4 Kuk 2, 4
KUK_34 กั๊ก 3, 4 Kuk 3, 4

เลี่ยม · Liam

Hole ไทย English
LIUM_12 เลี่ยม 1, 2 Lium 1, 2
LIUM_13 เลี่ยม 1, 3 Lium 1, 3
LIUM_14 เลี่ยม 1, 4 Lium 1, 4
LIUM_21 เลี่ยม 2, 1 Lium 2, 1
LIUM_23 เลี่ยม 2, 3 Lium 2, 3
LIUM_24 เลี่ยม 2, 4 Lium 2, 4
LIUM_31 เลี่ยม 3, 1 Lium 3, 1
LIUM_32 เลี่ยม 3, 2 Lium 3, 2
LIUM_34 เลี่ยม 3, 4 Lium 3, 4
LIUM_41 เลี่ยม 4, 1 Lium 4, 1
LIUM_42 เลี่ยม 4, 2 Lium 4, 2
LIUM_43 เลี่ยม 4, 3 Lium 4, 3

Fun Grasp

game = FunGrasp — 4 holes

Hole ไทย English
GREEN เขียว Green
RED แดง Red
WHITE ขาว White
YELLOW เหลือง Yellow

Event reference

Every event carries these three fields, so one handler can cover them all:

Field Type Meaning
event string which kind of event this is
roomCode string the room it belongs to, same code as in /rooms
at int64 epoch ms the event happened on our side, not when you received it

partner.round.opened

A new round is open and accepting bets.

Field Type Meaning
roundNo string round identifier; use it to de-duplicate
game string game name, same values as /rooms
startTime int64 epoch ms the round opened
bettingEndTime int64 epoch ms bets close — count down from this
shoeNo int shoe number, card games only
roundCount int round number within the shoe, card games only
{
  "event": "partner.round.opened",
  "roomCode": "BC-A",
  "at": 1793000000000,
  "roundNo": "BC-A20261030120000",
  "game": "Baccarat",
  "startTime": 1793000000000,
  "bettingEndTime": 1793000030000,
  "shoeNo": 7,
  "roundCount": 23
}

partner.round.betting_closed

Bets are closed for this round. Sent when bettingEndTime arrives, or earlier if the dealer closes the round early — in which case it always arrives before the result.

Field Type Meaning
roundNo string the round whose betting just closed
game string game name
{
  "event": "partner.round.betting_closed",
  "roomCode": "BC-A",
  "at": 1793000030300,
  "roundNo": "BC-A20261030120000",
  "game": "Baccarat"
}

partner.round.result

The round is closed and the result is final.

Field Type Meaning
roundNo string the round that just closed
game string game name
result string raw result as the game reports it, e.g. 3/4/5 for a dice game. See Betting holes for the hole keys each game settles onto
endTime int64 epoch ms the round closed
{
  "event": "partner.round.result",
  "roomCode": "HL-A",
  "at": 1793000045000,
  "roundNo": "HL-A20261030120000",
  "game": "Hilo",
  "result": "3/4/5",
  "endTime": 1793000045000
}

partner.round.cancelled

The round was cancelled and has no result. Anything you showed for it should be withdrawn.

Field Type Meaning
roundNo string the cancelled round
game string game name
reason string why, when the dealer gave one
{
  "event": "partner.round.cancelled",
  "roomCode": "BC-A",
  "at": 1793000040000,
  "roundNo": "BC-A20261030120000",
  "game": "Baccarat",
  "reason": "Card misdeal"
}

partner.room.maintenance

A room entered or left maintenance. isMa: true means there is nothing to watch, so take it off your screen; false means it is back. This is the same condition that keeps a room out of /rooms, pushed to you as it changes — /rooms alone would only tell you at your next call.

Field Type Meaning
isMa boolean true entering maintenance, false leaving it
roomName string the room's display name
{
  "event": "partner.room.maintenance",
  "roomCode": "BC-A",
  "at": 1793000100000,
  "isMa": true,
  "roomName": "Baccarat A"
}

Streaming APIs

Rooms and signed stream URLs.

List rooms with signed stream URLs

Every room that is not under maintenance (is_ma = false), limited to the rooms your partner account may see.

Rooms on a short break between dealers are included, flagged with isBreak: true — the video keeps flowing, so whether you show a holding card is your call.

Call this again before streamTtlSec elapses to get fresh links.

Authorizations:
(PartnerCodePartnerSecret)

Responses

Response samples

Content type
application/json
{}