Bet
Register a player bet
Called when a player places a bet. You must deduct the bet amount from the player's balance.
Endpoint
POST /betRequest
POST /bet HTTP/1.1
Host: your.game.api
X-Marbles-Signature: <signature>
Content-Type: application/json
{
"requestId": "8df0475e-5069-483a-8205-f6089997abc9",
"transactionId": "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",
"meta": {
"betType": "PickWinner",
"selection": [
"40e5e0eb-cc5a-4a81-a157-7a4b641c05df",
"17fcb2c6-f0ac-4855-98ef-9e7e3fd738bd",
"bb65a881-a4fe-4b65-aae5-e085a9f96cd3"
]
},
"timestamp": "2025-06-15T14:30:00.000Z"
}Request Fields
| Field | Type | Description |
|---|---|---|
requestId | string | Unique request identifier (UUID) |
transactionId | string | Unique transaction identifier for this bet |
clientSessionId | string | The player's session identifier |
clientPlayerId | string | The player's unique identifier |
roundId | string | The game round identifier |
gameId | string | The game identifier |
amount | int64 | Bet amount with 5-digit precision |
currency | string | ISO 4217 currency code |
isFree | boolean | true if this is a freebet (see below) |
rewardUuid | string | The reward identifier for freebets |
meta | object | Additional bet metadata |
meta.betType | string | Type of bet placed |
meta.selection | array | Selected items for the bet |
timestamp | string | ISO 8601 UTC timestamp of when the request was created |
Freebet Requests
When a player uses a freebet, the request includes additional fields:
{
"requestId": "...",
"transactionId": "...",
"amount": 0,
"currency": "USD",
"isFree": true,
"rewardUuid": "promo-winter-2025-001",
"meta": { ... }
}| Field | Description |
|---|---|
amount | Always 0 for freebets (no real money deducted) |
isFree | true to indicate this is a freebet |
rewardUuid | Your clientRewardId from when you granted the freebet |
For freebets, do not deduct any balance from the player. The amount will be 0. 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 bet.
status | When you return it | What 155 does |
|---|---|---|
SUCCESS | Bet accepted, stake debited | Bet is live |
INSUFFICIENT_BALANCE_ERROR | Player can't cover the stake | Bet rejected, surfaced to player |
DUPLICATE_TRANSACTION_ERROR | This transactionId was already processed | Treated as the original; no re-debit |
BET_LIMIT_REACHED_ERROR | Operator bet-limit hit | Bet rejected |
BONUS_ERROR | Free-bet/reward problem | Bet rejected |
UNKNOWN_ERROR | Unexpected operator-side failure | Bet rejected, retried |
Never return a bare failed to create bet message or a non-200 HTTP status — always return one of the status values above. ROUND_CLOSED is not a bet status: it's a 155-side condition, not something you return.
See Error codes for the canonical enum across all callbacks.
Idempotency
Replaying a /bet with the same transactionId must return DUPLICATE_TRANSACTION_ERROR with no balance change — it is a duplicate, not a new bet (network-retry safety). Do not debit the stake a second time.
This is asymmetric with /win: a replayed /win returns the original SUCCESS result, whereas a replayed /bet returns DUPLICATE_TRANSACTION_ERROR.
Aggregator (Hub88) integrations use a different status set — this page is for direct integrations.
Success Response
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
| Field | Type | Description |
|---|---|---|
status | string | "SUCCESS" |
requestId | string | Echo back the request ID |
clientPlayerId | string | Echo back the player ID |
currency | string | ISO 4217 currency code |
balance | int64 | New balance after bet (5-digit precision) |
Error Response
HTTP/1.1 200 OK
X-Marbles-Signature: <signature>
Content-Type: application/json
{
"status": "INSUFFICIENT_BALANCE_ERROR",
"requestId": "8df0475e-5069-483a-8205-f6089997abc9",
"clientPlayerId": "02mnrpyv2qd9jbwhoniyimxsy"
}Error Statuses
| Status | Description |
|---|---|
INSUFFICIENT_BALANCE_ERROR | Player does not have enough balance |
DUPLICATE_TRANSACTION_ERROR | This transactionId was already processed (idempotent replay) |
BONUS_ERROR | Bet does not pass free-bet / reward rules |
BET_LIMIT_REACHED_ERROR | Player has reached their betting limit |
UNKNOWN_ERROR | Bet could not be registered |
See the Response Contract above for what 155 does with each status, and Error codes for the canonical enum.