155API

Win

Register a winning or losing bet result


155 calls your wallet (signed with X-Marbles-Signature) to register a win or loss — the settlement of a bet. For winning bets, add the win amount to the player's balance. For losing bets, the amount is 0.

Endpoint

POST /win

Request

POST /win 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",
  "amount": 1000000,
  "currency": "USD",
  "roundClosed": true,
  "timestamp": "2025-06-15T14:30:00.000Z"
}

Request Fields

FieldTypeDescription
requestIdstringUnique request identifier (UUID)
transactionIdstringUnique transaction identifier for this win
referenceTransactionIdstringThe original bet transaction ID
clientSessionIdstringThe player's session identifier
clientPlayerIdstringThe player's unique identifier
roundIdstringThe game round identifier
gameIdstringThe game identifier
amountint64Win amount (0 for losses) with 5-digit precision
currencystringISO 4217 currency code
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. No more bets, wins, or rollbacks will occur for this round.
  • roundClosed: false - More transactions may follow for this round (e.g., multi-bet rounds).

Use roundClosed to finalize round records in your system. When true, you can safely mark the round as complete for reporting and reconciliation purposes. No /rollback will be sent for a bet after its /win callback/win (including the amount: 0 loss form) is the terminal callback for that bet.

Win vs Loss

  • Win: amount > 0 - Add this amount to the player's balance
  • Loss: amount = 0 - No balance change needed (bet was already deducted)

Freebet Results

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

{
  "requestId": "...",
  "transactionId": "...",
  "referenceTransactionId": "...",
  "amount": 1500000,
  "currency": "USD",
  "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
  • For wins: Credit the amount as real money to the player
  • For losses: amount is 0, no action needed

Freebet winnings are real money. When a freebet wins, credit the full win amount to the player's balance. See Freebets & Rewards for more details.

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 settlement.

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

statusWhen you return itWhat 155 does
SUCCESSWin/loss settled, balance updatedSettlement recorded
BONUS_ERRORFree-bet/reward settlement problemSettlement rejected
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 retry never moves money twice. The returned status for a replay differs by callback — this is the most common point of confusion:

CallbackReplay of the same transactionIdReturned statusBalance effect
/betRejected as a duplicate betDUPLICATE_TRANSACTION_ERRORunchanged
/winTreated as the original settlementSUCCESSunchanged
/rollbackTreated as the original rollbackSUCCESSunchanged

The asymmetry is deliberate. A replayed /bet is surfaced as DUPLICATE_TRANSACTION_ERROR — a duplicate is not a new bet, and flagging it tells 155 the stake was already debited. A replayed /win or /rollback returns plain SUCCESS: the settlement is simply re-confirmed, the money already moved once, and there is nothing to flag. In both cases the balance is unchanged — return success without crediting again; do not credit the win a second time and do not cancel the original credit.

Worked Examples

Success — first /win

The win settles and the player's balance reflects the credit.

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 /win — same transactionId

155 resent the callback. You return the original settlement result: still SUCCESS, balance unchanged (you do not credit the win 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
balanceint64New balance after win/loss (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"
}

Common Mistakes

  • Returning DUPLICATE_TRANSACTION_ERROR on a /win replay. That is the /bet rule. A replayed /win returns SUCCESS (see Idempotency).
  • Re-crediting on a replay. The money already moved on the first /win; a replay must not add the win amount again, and must not reverse the original credit.
  • Returning a non-200 HTTP status (or a bare error body). Always respond 200 with the outcome in status.

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

On this page