155API

Freebets & Rewards

Create promotional freebets and rewards for players


Freebets allow operators to create promotional rewards that give players free bets on 155.io games. When a player uses a freebet, no real money is deducted from their balance, but any winnings are credited as real money.

Free bets reuse the standard wallet callbacks — /bet, /win, /rollback — with two flags (isFree: true and a rewardUuid). The Contract rules section below is the authoritative, code-verified statement of the full grant → bet → win → rollback sequence and exactly what your wallet must return at each step. If you only read one section, read that one.

Enablement

Free bets are enabled by default for all new operators — there is nothing to request, and you can start granting them immediately. (Legacy operators predating this policy may still need the feature toggled; if your grant calls return FREEBETS_NOT_ENABLED, contact us to switch it on.)

Player Must Exist

The player must have launched at least one game before you can grant them freebets. The grant endpoint does not create players — if the player hasn't opened a game yet, the API will return a 404 PLAYER_NOT_FOUND error.

Contract rules: the flow & what to return

A free bet runs through the same four callbacks as a real-money bet — grant → /bet/win/rollback — but with amount: 0 on the bet leg and an isFree: true flag carried throughout. This section states, for each step, exactly what your wallet must do and return. These rules are verified against the 155 bet registry (direct-integration/bet_registry.go).

StepWhat 155 sendsWhat your wallet must doWhat you return
1. GrantYou call POST /game/free-bets/rewardsRecord the reward against the player; you'll see your clientRewardId echoed back later as rewardUuid201 Created with the reward + free-bet payload
2. /betisFree: true, amount: 0, rewardUuidDo not move the balance. Recognise the rewardUuidSUCCESS if the rewardUuid is known; BONUS_ERROR if it is not
3. /winisFree: true, referenceTransactionId = the bet's transactionIdOn a win, credit the full amount (real money). On a loss, the amount is 0 — credit nothingSUCCESS
4. /rollbackisFree: true (fires only before /win)Reverse the bet leg. There is nothing to refund (the bet debited 0)SUCCESS (or DUPLICATE_TRANSACTION_ERROR for a replay)

Unknown rewardUuid → return BONUS_ERROR (never UNKNOWN_ERROR)

When you receive a free /bet whose rewardUuid you do not recognise, return BONUS_ERROR — not UNKNOWN_ERROR. 155 maps BONUS_ERROR to a bonus failure and cleanly rejects the bet; any other status (including UNKNOWN_ERROR) is treated as a wallet fault and is not what 155 expects here. This is the single most common free-bet integration mistake. See the full enum in Error codes.

Zero debit — a free /bet must not touch the balance

A free /bet arrives with isFree: true and amount: 0. It must not debit (or credit) the player. Returning INSUFFICIENT_BALANCE_ERROR on a free bet is wrong — there is nothing to debit. Just return SUCCESS (or BONUS_ERROR if the rewardUuid is unknown).

Free-bet winnings are REAL money

A free bet is free to place, but what it pays out is real. On a winning /win, credit the full amount to the player's real balance. On a losing /win the amount is 0 — credit nothing. Never invent a phantom credit for a losing free bet, and never withhold a real win because the bet was free.

Rollback of a settled / duplicate free bet → return SUCCESS

A /rollback for a free bet — including one you have already settled or already rolled back — must return SUCCESS (balance unchanged). 155 accepts a rollback response of SUCCESS or DUPLICATE_TRANSACTION_ERROR; any other status is treated as a failure. So a settled/duplicate free-bet rollback is forgiving: silently dedupe and answer SUCCESS. See /rollback for the shared idempotency rule across all bets.

Cross-references: the per-callback request/response shapes live on /bet, /win, and /rollback; the canonical status enum lives in Error codes.

Integration Options

Direct integration operators can grant freebets to players via the 155.io API and receive freebet transactions through their operator API. Free bets are enabled by default — see Enablement above. For the authoritative grant → bet → win → rollback behaviour, see Contract rules.

Granting Freebets

Use the 155.io API to grant freebets to players:

POST /game/free-bets/rewards

Request

{
  "clientPlayerId": "player-123",
  "operatorId": "your-operator-id",
  "clientRewardId": "promo-winter-2025-001",
  "amount": 500000,
  "currency": "USD",
  "quantity": 3,
  "expiresAt": "2025-12-31T23:59:59Z",
  "gameIds": ["game-uuid-1", "game-uuid-2"]
}
FieldTypeRequiredDescription
clientPlayerIdstringYesThe player's unique identifier in your system
operatorIdstringYesYour operator ID
clientRewardIdstringYesYour unique identifier for tracking this reward
amountintegerYesValue per freebet with 5-digit precision (e.g., 500000 = $5.00)
currencystringYesISO 4217 currency code
quantityintegerNoNumber of freebets to grant (default: 1, max: 100)
expiresAtstringNoISO 8601 expiration datetime
startTimestringNoISO 8601 datetime when freebets become available (for scheduled campaigns)
gameIdsarrayNoRestrict freebets to specific games (omit for all games)

Success Response

HTTP/1.1 201 Created

{
  "reward": {
    "type": "Reward",
    "clientRewardId": "promo-winter-2025-001",
    "clientPlayerId": "player-123",
    "operatorId": "your-operator-id",
    "amount": 500000,
    "currency": "USD",
    "quantity": 3,
    "applicableGames": ["game-uuid-1", "game-uuid-2"],
    "meta": {},
    "startTime": null,
    "endTime": "2025-12-31T23:59:59Z",
    "status": "granted",
    "createdAt": "2025-06-15T14:30:00Z"
  },
  "freeBets": [
    {
      "id": "fb-001",
      "amount": 500000,
      "currency": "USD",
      "status": "claimable",
      "createdAt": "2025-06-15T14:30:00Z",
      "expiresAt": "2025-12-31T23:59:59Z",
      "applicableGames": ["game-uuid-1", "game-uuid-2"]
    },
    {
      "id": "fb-002",
      "amount": 500000,
      "currency": "USD",
      "status": "claimable",
      "createdAt": "2025-06-15T14:30:00Z",
      "expiresAt": "2025-12-31T23:59:59Z",
      "applicableGames": ["game-uuid-1", "game-uuid-2"]
    },
    {
      "id": "fb-003",
      "amount": 500000,
      "currency": "USD",
      "status": "claimable",
      "createdAt": "2025-06-15T14:30:00Z",
      "expiresAt": "2025-12-31T23:59:59Z",
      "applicableGames": ["game-uuid-1", "game-uuid-2"]
    }
  ]
}

Reward Status

The reward status will be "granted" when freebets are immediately available, or "scheduled" if startTime is in the future.

Error Responses

HTTP CodeError CodeDescription
400VALIDATION_ERRORInvalid request (missing fields, invalid format)
400FREEBETS_NOT_ENABLEDFreebets not enabled for your operator (only legacy accounts predating the default-on policy — contact us to toggle it on)
404PLAYER_NOT_FOUNDPlayer does not exist
409REWARD_ALREADY_EXISTSA reward with this clientRewardId already exists
500UNKNOWN_ERRORInternal server error

Client Reward ID

The clientRewardId is returned in bet transactions as rewardUuid, allowing you to track which promotion a freebet belongs to.

Important: Each clientRewardId is tied to one player. If you want to grant freebets to 100 players in a campaign, you make 100 API calls. You can use the same clientRewardId pattern (e.g., winter-promo-{playerId}) or unique IDs per grant.

Each free bet settles independently — not aggregated

A grant is a pool of independent free-bet credits, not a slots-style free-spins session. Each free bet is its own /bet (isFree: true, amount: 0, with rewardUuid) followed by its own per-round /win (paid as real money, or amount: 0 for a loss). So N free bets = N /bet + N /win callbacks — we do not send a single batched win, and the number of wins won't necessarily equal the granted quantity (unused free bets are cancelled/expired, not settled). Group a grant's settlements by the shared rewardUuid.

Cancelling Freebets

Cancel unused freebets for a specific reward:

POST /game/free-bets/rewards/cancel
{
  "clientRewardId": "promo-winter-2025-001",
  "operatorId": "your-operator-id",
  "reason": "Player requested cancellation"
}

Cancel Response

{
  "reward": {
    "type": "Reward",
    "clientRewardId": "promo-winter-2025-001",
    "clientPlayerId": "player-123",
    "operatorId": "your-operator-id",
    "amount": 500000,
    "currency": "USD",
    "quantity": 2,
    "applicableGames": [],
    "meta": {},
    "status": "cancelled",
    "createdAt": "2025-06-15T14:30:00Z",
    "cancelledAt": "2025-07-01T10:00:00Z"
  },
  "freeBets": [
    {
      "id": "fb-001",
      "amount": 500000,
      "currency": "USD",
      "status": "cancelled",
      "createdAt": "2025-06-15T14:30:00Z",
      "expiresAt": "2025-12-31T23:59:59Z",
      "applicableGames": []
    },
    {
      "id": "fb-002",
      "amount": 500000,
      "currency": "USD",
      "status": "cancelled",
      "createdAt": "2025-06-15T14:30:00Z",
      "expiresAt": "2025-12-31T23:59:59Z",
      "applicableGames": []
    }
  ]
}

Cancel Rules

  • Only freebets with status claimable or claimed can be cancelled
  • If any freebet from the reward has been used, the entire reward cannot be cancelled
  • Cancellation is per-reward (per-player), not campaign-wide
  • Scheduled rewards (where startTime is in the future) can be cancelled before the freebets are generated. The reward is transitioned to cancelled and a REWARD_NOT_STARTED response is returned with no freeBets payload.

Cancel Error Responses

HTTP CodeError CodeCodeDescription
404REWARD_NOT_FOUND9001No reward exists for the provided clientRewardId
409REWARD_CANNOT_BE_CANCELLED9006At least one freebet has already been used — the reward cannot be cancelled
409REWARD_NOT_STARTED9007Reward was scheduled for a future startTime; freebets hadn't been generated yet. The reward has been transitioned to cancelled — treat this as a successful cancellation
500UNKNOWN_ERRORInternal server error

Freebet Statuses

StatusDescription
claimableAvailable for the player to use
claimedPlayer has selected but not yet placed a bet
usedFreebet was used to place a bet
expiredFreebet expired before being used
cancelledFreebet was cancelled by operator

Scheduling Freebets

Use startTime to schedule freebets for a future date (e.g., for upcoming promotions):

{
  "clientPlayerId": "player-123",
  "operatorId": "your-operator-id",
  "clientRewardId": "new-years-2026-player123",
  "amount": 1000000,
  "currency": "USD",
  "quantity": 5,
  "startTime": "2026-01-01T00:00:00Z",
  "expiresAt": "2026-01-31T23:59:59Z"
}
  • Freebets are created immediately but only become claimable after startTime
  • Players won't see the freebets until startTime
  • You can cancel scheduled freebets before they become active

Receiving Freebet Transactions

When a player uses a freebet, you'll receive modified bet/win/rollback requests:

Bet Request (Freebet)

{
  "requestId": "8df0475e-5069-483a-8205-f6089997abc9",
  "transactionId": "ea0240f5-483d-434b-a8d4-04dabf61cde3",
  "clientPlayerId": "player-123",
  "roundId": "17cc81fd-df13-4ca4-857d-de0f766dc372",
  "gameId": "f1c0b104-f29d-44a9-ae93-e8afcbe3feb9",
  "amount": 0,
  "currency": "USD",
  "isFree": true,
  "rewardUuid": "promo-winter-2025-001",
  "meta": { ... }
}

Key differences for freebets:

  • amount is 0 (no real money deducted)
  • isFree is true
  • rewardUuid contains your clientRewardId for tracking

Win/Loss Request (Freebet)

{
  "requestId": "...",
  "transactionId": "...",
  "referenceTransactionId": "ea0240f5-483d-434b-a8d4-04dabf61cde3",
  "amount": 1500000,
  "currency": "USD",
  "isFree": true,
  "roundClosed": true
}
  • For wins: amount contains the winnings to credit (this is real money)
  • For losses: amount is 0 (nothing to credit or deduct)
  • isFree is true to indicate this was a freebet result

Rollback Request (Freebet)

{
  "requestId": "...",
  "transactionId": "...",
  "referenceTransactionId": "ea0240f5-483d-434b-a8d4-04dabf61cde3",
  "isFree": true,
  "roundClosed": true
}
  • isFree is true to indicate the original bet was a freebet
  • No amount to refund (freebet had amount: 0)
  • Fires only before the freebet's /win (win or loss) callback. To reverse a granted-but-unused reward, use Cancelling Freebets, not /rollback.

Example Flow

  1. You grant a $5 freebet to player-123 via the API
  2. Player launches a 155.io game and sees the freebet in their inventory
  3. Player taps the freebet and selects "Use now" to activate it
  4. Player places a bet (freebet is applied)
  5. You receive a bet request with amount: 0, isFree: true
  6. Round completes - player wins $15
  7. You receive a win request with amount: 1500000, isFree: true
  8. You credit $15 to the player's real balance

Hub88 operators use Hub88's native freebet API and receive transactions through Hub88's standard integration.

Step 1: Request Prepaid Templates

Contact us to set up your freebet templates. We'll need:

InformationDescription
Operator IDYour Hub88 operator_id
Bet valueAmount per free bet (e.g., $1, $5, $10)
QuantityNumber of free bets in the reward
CurrencyWhich currencies to support (e.g., USD, EUR)
GamesAll 155.io games or specific games only

For example, a template with bet value: $2 and quantity: 5 gives the player 5 free bets worth $2 each.

Once configured, you'll receive prepaid_uuid(s) that you can use to create rewards.

Step 2: Create Rewards via Hub88

Use Hub88's Operator API to grant freebets to your players:

POST /operator/generic/v2/freebet/rewards/create
{
  "operator_id": "your-operator-id",
  "user": "player-123",
  "prepaid_uuid": "uuid-from-step-1",
  "start_time": "2025-01-01T00:00:00Z",
  "end_time": "2025-12-31T23:59:59Z"
}

See Hub88's Freebets API Documentation for full details.

Set Expiration Dates

Always set start_time and end_time when creating rewards. Otherwise, rewards will automatically expire after a few weeks.

How It Works

  1. You create a reward for a player via the appropriate API
  2. Player launches a 155.io game and sees the freebet in their inventory
  3. Player taps the freebet and selects "Use now" to activate it
  4. Player places a bet (the freebet is automatically applied, no real balance deducted)
  5. Winnings are credited as real money to the player's balance

Manual Activation Required

Freebets are not automatically used. Players must manually select a freebet from their inventory before placing a bet. This gives players control over when to use their promotional rewards. Only one freebet can be active at a time.

Need Help?

Free bets are enabled by default for new operators (see Enablement). Contact us to discuss promotional strategies, or if a legacy operator account still needs the feature toggled on.

On this page