155API

Rollback

Reverse a previously registered bet


155 calls your wallet (signed with X-Marbles-Signature) to reverse a previously registered /bet — for example when a round is cancelled or errors out before settlement. You must refund the stake to the player's balance.

When This Fires

/rollback only fires before /win has been sent for a given bet. Once /win is delivered (regardless of amount, including the amount: 0 loss form), the round is terminal — no /rollback will follow.

Triggers for /rollback:

  • The round was cancelled before settlement
  • The player's bet timed out during chip placement
  • /bet was received and acknowledged, but a downstream error required us to reverse the debit before the round settled

Not for Reversing Settlements

To reverse a granted-but-unused freebet, use POST /game/free-bets/rewards/cancel — not /rollback. See Freebets & Rewards.

Endpoint

POST /rollback

Request

POST /rollback HTTP/1.1
Host: your.game.api
X-Marbles-Signature: <signature>
Content-Type: application/json

{
  "requestId": "8df0475e-5069-483a-8205-f6089997abc9",
  "transactionId": "9ea48131-3a0f-4067-94d0-3212e7e25abb",
  "referenceTransactionId": "ea0240f5-483d-434b-a8d4-04dabf61cde3",
  "clientSessionId": "0k3cz83bb3h2vn53ocnc7pxw9",
  "clientPlayerId": "02mnrpyv2qd9jbwhoniyimxsy",
  "roundId": "17cc81fd-df13-4ca4-857d-de0f766dc372",
  "gameId": "f1c0b104-f29d-44a9-ae93-e8afcbe3feb9",
  "roundClosed": true,
  "timestamp": "2025-06-15T14:30:00.000Z"
}

Request Fields

FieldTypeDescription
requestIdstringUnique request identifier (UUID)
transactionIdstringUnique transaction identifier for this rollback
referenceTransactionIdstringThe original bet transaction ID being rolled back
clientSessionIdstringThe player's session identifier
clientPlayerIdstringThe player's unique identifier
roundIdstringThe game round identifier
gameIdstringThe game identifier
isFreebooleantrue if the original bet was a freebet
rewardUuidstringThe clientRewardId from the original freebet grant (only present when isFree is true)
roundClosedbooleanWhether this transaction closes the round (see below)
timestampstringISO 8601 UTC timestamp of when the request was created

Round Lifecycle

The roundClosed field indicates whether this is the final transaction for a round:

  • roundClosed: true - This is the final transaction. The round is cancelled and no more transactions will occur.
  • roundClosed: false - More transactions may follow (rare for rollbacks, but possible in multi-bet scenarios).

Use roundClosed to finalize round records in your system. When true, you can safely mark the round as cancelled/voided for reporting purposes.

The Rollback-to-Zero Rule

Restore the stake — nothing more, nothing less

A /rollback refunds the stake so the balance returns to exactly what it was before the bet — restore the stake, never re-debit, never double-refund.

The net effect of /bet followed by /rollback must be zero: the player ends with the same balance they had before the bet was placed. Refund the original stake (the amount from the referenced /bet) and stop there. Do not deduct anything, and do not refund a stake that was already refunded — see Idempotency below.

Freebet Rollbacks

When the original bet was a freebet, the request includes isFree: true:

{
  "requestId": "...",
  "transactionId": "...",
  "referenceTransactionId": "...",
  "isFree": true,
  "rewardUuid": "promo-winter-2025-001",
  "roundClosed": true
}
  • isFree is true to indicate the original bet was a freebet
  • rewardUuid contains your clientRewardId for tracking which promotion this freebet belongs to
  • Pass isFree and rewardUuid through unchanged so the rollback maps to the correct grant
  • No balance refund needed (the original freebet had amount: 0) — mark the freebet as cancelled in your records

Rolling back an already-settled freebet is treated as a duplicate and silently deduped — return SUCCESS, balance unchanged. See Freebets & Rewards for the full reward flow.

Response Contract

Always respond HTTP 200; put the outcome in status. We read the status field, not the HTTP code, to decide what happens to the rollback.

The full status set lives in Error codes — that is the canonical home for the enum across all callbacks. For /rollback the relevant outcomes are:

statusWhen you return itWhat 155 does
SUCCESSStake refunded (or already rolled back)Rollback recorded
UNKNOWN_ERRORUnexpected operator-side failure155 retries

Never return a non-200 HTTP status or a bare error body — always respond 200 with one of the status values above. A non-200 is read as a transport failure and may trigger retries before the body is parsed.

Idempotency

Networks retry, so 155 may resend a callback it isn't certain landed. Dedupe by transactionId so a replay never refunds the stake twice. A replayed /rollback is treated as the original rollback: return plain SUCCESS with the balance unchanged — the stake was already restored once, and there is nothing more to refund.

This matches /win, which uses the same success-dedupe rule, and is asymmetric with /bet: a replayed /bet returns DUPLICATE_TRANSACTION_ERROR, whereas a replayed /rollback (like /win) returns SUCCESS.

Worked Examples

Success — first /rollback

The stake is refunded and the player's balance returns to exactly what it was before the bet.

HTTP/1.1 200 OK
X-Marbles-Signature: <signature>
Content-Type: application/json

{
  "status": "SUCCESS",
  "requestId": "8df0475e-5069-483a-8205-f6089997abc9",
  "clientPlayerId": "02mnrpyv2qd9jbwhoniyimxsy",
  "currency": "USD",
  "balance": 1000000
}

Replayed /rollback — same transactionId

155 resent the callback. You return the original rollback result: still SUCCESS, balance unchanged (the stake was already refunded once — do not refund again).

HTTP/1.1 200 OK
X-Marbles-Signature: <signature>
Content-Type: application/json

{
  "status": "SUCCESS",
  "requestId": "8df0475e-5069-483a-8205-f6089997abc9",
  "clientPlayerId": "02mnrpyv2qd9jbwhoniyimxsy",
  "currency": "USD",
  "balance": 1000000
}

Response Fields

FieldTypeDescription
statusstring"SUCCESS"
requestIdstringEcho back the request ID
clientPlayerIdstringEcho back the player ID
currencystringISO 4217 currency code
balanceint64Balance after rollback — equals the pre-bet balance (5-digit precision)

Error Response

HTTP/1.1 200 OK
X-Marbles-Signature: <signature>
Content-Type: application/json

{
  "status": "UNKNOWN_ERROR",
  "requestId": "8df0475e-5069-483a-8205-f6089997abc9",
  "clientPlayerId": "02mnrpyv2qd9jbwhoniyimxsy"
}

See the Response Contract above for what 155 does with each status, and Error codes for the canonical enum.

On this page