Round lookup & replay
API · Operator → Boss HubSearches rounds by player, game, status and date. For a single round, GET /v1/rounds/{round_id} also returns the transactions and the replay link. You only see your own rounds, in the environment you call. Requires the rounds.read scope. The endpoints that list and resolve stuck rounds are at the end of the page.
Headers
| Header | Description |
|---|---|
| X-Operator-Id | Your operator ID |
| X-Timestamp | Unix seconds. Rejected outside ±30 s |
| X-Signature | hex(HMAC_SHA256(secret, ts + "." + METHOD + "." + path?query + "." + body)) |
| X-Api-Key | Optional. Selects the right secret when you have several keys |
A single round and its transactions
GET /v1/rounds/{round_id} returns all round fields, the transactions array in creation order and replay_url. round_id is a path parameter, e.g. rnd_01HF3K9QZ2. If the round does not exist, is in the other environment or is not yours, you get 404 NOT_FOUND.
{
"items": [
{
"id": "rnd_01HF3K9QZ2",
"session_id": "ses_01HF3K7M",
"site_id": "site_mrd01",
"player_id": "u_88213",
"game_id": "sultans-ember",
"currency": "USD",
"bet": 2.00,
"win": 5.00,
"freeround_win": 0.00,
"jackpot_win": 0.00,
"status": "closed",
"kind": "normal",
"is_freeround": false,
"has_jackpot": false,
"rtp_variant": "v96",
"game_version": "1.4.2",
"created_at": "2026-11-05T14:22:05.120Z",
"closed_at": "2026-11-05T14:22:09.480Z"
}
],
"next_cursor": null
}{
"id": "rnd_01HF3K9QZ2",
"session_id": "ses_01HF3K7M",
"site_id": "site_mrd01",
"player_id": "u_88213",
"game_id": "sultans-ember",
"currency": "USD",
"bet": 2.00,
"win": 5.00,
"freeround_win": 0.00,
"jackpot_win": 0.00,
"status": "closed",
"kind": "normal",
"is_freeround": false,
"has_jackpot": false,
"rtp_variant": "v96",
"game_version": "1.4.2",
"created_at": "2026-11-05T14:22:05.120Z",
"closed_at": "2026-11-05T14:22:09.480Z",
"transactions": [
{
"transaction_id": "tx_01HF3K9QZ2-b1",
"type": "bet",
"status": "ok",
"amount": 2.00,
"capped_from": null,
"balance_after": 148.60,
"http_status": 200,
"attempts": 1,
"latency_ms": 84,
"operator_tx_id": "op_tx_9921844",
"request_id": "req_01HF3KA2",
"ref_transaction_id": null,
"created_at": "2026-11-05T14:22:05.120Z",
"booked_at": "2026-11-05T14:22:09.480Z"
},
{
"transaction_id": "tx_01HF3K9QZ2-w1",
"type": "win",
"status": "ok",
"amount": 5.00,
"capped_from": null,
"balance_after": 153.60,
"http_status": 200,
"attempts": 1,
"latency_ms": 91,
"operator_tx_id": "op_tx_9921845",
"request_id": "req_01HF3KA7",
"ref_transaction_id": null,
"created_at": "2026-11-05T14:22:09.480Z",
"booked_at": "2026-11-05T14:22:09.480Z"
}
],
"replay_url": "https://replay.provider.example/rnd_01HF3K9QZ2"
}{
"code": "NOT_FOUND",
"message": "Record not found.",
"request_id": "req_01HF3Q2N"
}Round statuses
| Status | Meaning |
|---|---|
| open | The round is open. |
| closed | The round has closed; closed_at is set. |
| rolled_back | All bets and wins were reversed or voided, and at least one was reversed. |
| void | No money moved. Hidden from lists unless you filter for it. |
| stuck | The round has an item awaiting resolution. This is not a stored status; it shows while an item is open, and the round returns to its real status when the item closes. |
Round fields
| Field | Type | Description |
|---|---|---|
| id | string | Round ID. Used as round_id in callbacks. |
| session_id | string | The game session. |
| site_id | string | Site ID. |
| player_id | string | The player ID on the operator side. |
| game_id | string | Game code. |
| currency | ISO 4217 | Round currency. |
| bet | decimal(18,2) | Net bet total, with reversals deducted. |
| win | decimal(18,2) | Net win total: regular win + freeround_win + jackpot_win. |
| freeround_win | decimal(18,2) | Free round win. |
| jackpot_win | decimal(18,2) | Jackpot win. |
| status | string | Round status, see above. |
| kind | string | normal, freeround, bonus_buy, promo. promo: a betless promotional credit round (tournament prize); the amount is in the transaction list, not in win. |
| is_freeround | boolean | A free round. |
| has_jackpot | boolean | The round includes a jackpot drop. |
| rtp_variant | string | null | RTP variant played, e.g. v96. |
| game_version | string | null | Game version played, e.g. 1.4.2. |
| created_at | date-time | When the round opened. |
| closed_at | date-time | null | When the round closed. The billing period follows this moment. |
Transaction fields
| Field | Type | Description |
|---|---|---|
| transaction_id | string | The transaction ID sent in the callback. |
| type | string | bet, win, rollback. |
| status | string | queued, pending, ok, rejected, ambiguous, reversed, void, manual_ok. |
| amount | decimal(18,2) | Transaction amount. |
| capped_from | decimal(18,2) | null | When the free round win cap reduced the payment, the amount the game showed; amount is what was paid. Show both in the player’s history. |
| balance_after | decimal(18,2) | null | The balance in your reply. |
| http_status | integer | null | The HTTP code of your reply. |
| attempts | integer | Number of attempts. |
| latency_ms | integer | null | Reply time, in ms. |
| operator_tx_id | string | null | The transaction ID in your reply. |
| request_id | string | The X-Request-Id of the callback. |
| ref_transaction_id | string | null | On a rollback, the transaction it reverses. |
| created_at | date-time | When the transaction was created. |
| booked_at | date-time | null | The accounting date. Reports and invoices read this date. |
Replay
replay_url is the link for watching the round again. It is null when the provider offers no replay, the round has no provider reference, the provider cannot be reached at that moment, or your replay module is disabled. The link is time-limited and can be revoked; keep that in mind when sharing it for support or a dispute.
Error codes
| Code | HTTP | Meaning |
|---|---|---|
| INVALID_SIGNATURE | 401 | Signature could not be verified |
| TIMESTAMP_SKEW | 401 | X-Timestamp is outside ±30 s |
| IP_NOT_ALLOWED | 403 | IP is not on the allowlist |
| SCOPE_MISSING | 403 | The rounds.read scope is missing |
| SCOPE_DENIED | 403 | site_id or the round is outside your key’s scope |
| NOT_FOUND | 404 | The round does not exist or is not yours |
| VALIDATION_ERROR | 422 | Invalid query parameter |
| INVALID_CURSOR | 422 | cursor did not come from a previous response |
| RATE_LIMITED | 429 | Rate limit exceeded |
Stuck rounds
GET /v1/reconciliation/stuck-rounds (reconciliation.read) returns the reconciliation items awaiting resolution, oldest first: at most 500 rows, no pagination. Each open item is one row; the same round can appear twice. Open item statuses: open, retrying, on_hold, escalated. When a round gets stuck, the round.stuck webhook arrives too.
| Field | Type | Description |
|---|---|---|
| … | All Round fields (above). | |
| item_id | string | The reconciliation item ID. |
| issue | string | win_no_response, win_rejected, bet_timeout, rollback_rejected, duplicate_conflict, win_without_bet, win_invalid, rollback_after_win, rollback_after_jackpot, round_open_timeout. |
| transaction_id | string | null | The item’s transaction. |
| pending_call | string | null | The pending call: bet, win, rollback. |
| item_status | string | open, retrying, on_hold, escalated. |
| age_seconds | integer | Age of the item, in seconds. |
| manual_unlock_at | date-time | null | When the manual close options unlock. |
| attempts | object[] | Attempts: at, result. |
[
{
"id": "rnd_01HF3M2C7R",
"session_id": "ses_01HF3M1Q",
"site_id": "site_mrd01",
"player_id": "u_88213",
"game_id": "sultans-ember",
"currency": "USD",
"bet": 2.00,
"win": 0.00,
"freeround_win": 0.00,
"jackpot_win": 0.00,
"status": "stuck",
"kind": "normal",
"is_freeround": false,
"has_jackpot": false,
"rtp_variant": "v96",
"game_version": "1.4.2",
"created_at": "2026-11-05T15:02:11.000Z",
"closed_at": null,
"item_id": "rci_01HF3M4A",
"issue": "win_no_response",
"transaction_id": "tx_01HF3M2C7R-w1",
"pending_call": "win",
"item_status": "retrying",
"age_seconds": 640,
"manual_unlock_at": null,
"attempts": [
{ "at": "2026-11-05T15:02:14.000Z", "result": "timeout" },
{ "at": "2026-11-05T15:02:44.000Z", "result": "HTTP 502" }
]
}
]Resolving a stuck round
POST /v1/reconciliation/stuck-rounds/{round_id}/resolve (reconciliation.write, X-Request-Id required) decides on an open item of the round. The reply is 202: {status, approval_id}. status: applied means it was applied; pending_approval means it waits for Boss Hub approval.
| issue | action | manual_close outcome |
|---|---|---|
| win_no_response, win_rejected | resend_win, manual_close, cancel_result, escalate | operator_paid |
| bet_timeout | rollback, manual_close, escalate | not_taken |
| rollback_rejected | bet refund: rollback, manual_close, escalate; win or jackpot reversal: also rollback_refuse | not_taken (bet), win_reversed (win, jackpot) |
| duplicate_conflict | the row above for the transaction’s type; for an inbound event conflict manual_close, escalate | by transaction; invalid for an inbound event |
| win_without_bet, win_invalid | manual_close, escalate | invalid |
| rollback_after_win | rollback_refuse, rollback_accept, escalate | |
| rollback_after_jackpot | drop_keep, drop_cancel, escalate | |
| round_open_timeout | manual_close, rollback, escalate | lost |
- Always need Boss Hub approval: cancel_result, rollback_accept, drop_cancel. In a round with a jackpot drop, cancel_result and rollback_accept run as drop_cancel.
- No approval needed: rollback_refuse, drop_keep, escalate and manual_close + operator_paid.
- resend_win, rollback and the other manual_close outcomes go to approval when the round’s largest bet or win exceeds the approval threshold (1,000 USD by default).
- On a transaction that has been attempted, manual_close gets 409 MANUAL_LOCKED until the schedule is stopped with Resolve in the portal or with escalate, and manual_unlock_at has passed. Manual payment rule: win.
POST /v1/reconciliation/stuck-rounds/rnd_01HF3M2C7R/resolve
{
"action": "resend_win",
"reason": "Wallet was down 15:00-15:10, retry the win",
"transaction_id": "tx_01HF3M2C7R-w1"
}
202
{ "status": "applied", "approval_id": null }Resolution error codes
| Code | HTTP | Meaning |
|---|---|---|
| SCOPE_MISSING | 403 | The reconciliation.read or reconciliation.write scope is missing |
| SCOPE_DENIED | 403 | site_id or the round is outside your key’s scope |
| NOT_FOUND | 404 | The round has no open item |
| ITEM_RESOLVED | 409 | The item is already resolved |
| MANUAL_LOCKED | 409 | The manual option is still locked (details.manual_unlock_at) |
| APPROVAL_PENDING | 409 | An approval is already pending for this item |
| TX_NOT_RESENDABLE | 409 | The transaction cannot be resent in its current state |
| TX_CHANGED | 409 | The transaction changed in the meantime; reload the list and decide again |
| NO_TRANSACTION | 409 | The round has no suitable transaction for this resolution |
| TRANSACTION_REQUIRED | 422 | Several open items, transaction_id is required (details.transaction_ids) |
| TRANSACTION_MISMATCH | 422 | transaction_id is not an open item of this round (details.transaction_ids) |
| ACTION_NOT_ALLOWED | 422 | This action cannot be used for this item |
| OUTCOME_NOT_ALLOWED | 422 | outcome is missing or cannot be used for this item |
| OPERATOR_CONFIRMATION_REQUIRED | 422 | Cancelling a manually paid win needs operator_confirmed: true |
| VALIDATION_ERROR | 422 | Missing or invalid field, older_than format |