Gift API (Free Bets)
The Gift API lets Operators grant, cancel, and track free bets (a.k.a. gifts) for their players. Unlike the Wallet API — where Game Provider calls you — the Gift API is outbound from the Operator: you call Game Provider.
[!IMPORTANT] All monetary values in this API are integers in millis (1/1000th of the main currency unit). This includes
betLevelon grant, balances returned byGET free-bet balance, and every amount you will later see onFREE_BET/FREE_BET_WINwallet callbacks. No floats, ever.Examples:
100= 0.10 USD,5000= 5.00 EUR,1_000_000= 1 000.00 USD.
Summary
| # | Endpoint | Direction | Purpose |
|---|---|---|---|
| 1 | POST /api/v1/game-gifts |
Operator → Game Provider | Grant one or more free-bet gifts to a player. |
| 2 | POST /api/v1/game-gifts/cancel |
Operator → Game Provider | Cancel previously granted gifts by key. |
| 3 | GET /api/v1/game-free-bet/{sessionToken} |
Game → Game Provider | Read the active free-bet balance during a game session (consumed by the game client). Operators normally do not call this. |
All Operator-initiated calls require X-Public-Key and X-Signature headers — see Authentication & Security.
Data Types
| Type | Rule |
|---|---|
Money (betLevel, balances, win amounts) |
Integer, millis (1/1000th of the unit). |
Counts (quantity) |
Integer, > 0. |
Dates (activationDate, expirationDate) |
ISO 8601 local date-time, no zone (e.g. 2026-05-01T00:00:00). Interpreted in UTC. |
Currency (currencyCode) |
3-letter ISO 4217 (USD, EUR, …). |
Identifiers (giftKey, operatorTxId, userId) |
Opaque strings. Operator-generated. Must be unique where marked. |
1. Grant Gifts
Award one or more free-bet gifts to a single player. Each gift entitles the player to a fixed number of rounds (quantity) at a fixed stake (betLevel, in millis) on a specific gameName.
- Endpoint:
POST {BASE_URL}/api/v1/game-gifts - Security:
X-Public-Key,X-Signature(HMAC-SHA256 of raw body, Base64-encoded).
Request
{
"portalName": "MyCasino",
"client": {
"operatorTxId": "gift-tx-001",
"userId": "player123",
"currencyCode": "USD"
},
"gifts": [
{
"gameName": "chicken-race",
"giftKey": "promo-welcome-2026-04-player123-01",
"quantity": 10,
"betLevel": 100,
"activationDate": "2026-04-15T00:00:00",
"expirationDate": "2026-04-30T23:59:59"
},
{
"gameName": "aviadrone",
"giftKey": "promo-welcome-2026-04-player123-02",
"quantity": 5,
"betLevel": 500,
"activationDate": "2026-04-15T00:00:00",
"expirationDate": "2026-04-30T23:59:59"
}
]
}
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
portalName |
String | Yes | Your portal / brand name as registered with Game Provider. |
client.operatorTxId |
String | Yes | Your unique transaction ID for this grant operation. Use for retries and correlation. |
client.userId |
String | Yes | Player ID on your side. |
client.currencyCode |
String | Yes | 3-letter ISO currency. Must match the player's wallet currency. |
gifts[] |
Array | Yes | One or more gifts to grant in this call. |
gifts[].gameName |
String | Yes | Game identifier (same value you'd use as {game} in the Launch API). |
gifts[].giftKey |
String | Yes — globally unique | Your idempotency key for this specific gift. Re-sending the same giftKey will not create a duplicate. |
gifts[].quantity |
Integer | Yes | Number of rounds the player can play for free. Must be > 0. |
gifts[].betLevel |
Long (millis) | Yes | Stake per round in millis. Example: 100 = 0.10 USD per round. |
gifts[].activationDate |
ISO date-time | Yes | Gift becomes playable from this moment. |
gifts[].expirationDate |
ISO date-time | Yes | Gift expires at this moment. Must be after activationDate. |
Response
{
"code": "OK",
"gifts": [
{ "giftKey": "promo-welcome-2026-04-player123-01", "granted": true, "code": "OK" },
{ "giftKey": "promo-welcome-2026-04-player123-02", "granted": false, "code": "10026" }
]
}
Response fields
| Field | Type | Description |
|---|---|---|
code |
String | Overall request status. OK means the request reached the service and each gift has an individual result; an error code here means the whole batch was rejected. |
gifts[] |
Array | One entry per gift in the request, in order. |
gifts[].giftKey |
String | Echo of the request key. |
gifts[].granted |
Boolean | true if this specific gift was accepted. |
gifts[].code |
String | Per-gift status. OK on success, otherwise an error code. |
[!TIP] Always branch on per-gift
gifts[].granted— a batch can succeed overall but partially fail.
2. Cancel Gifts
Cancel one or more previously granted gifts by giftKey. Cancellation is final: a canceled gift cannot be reactivated. Already-consumed rounds are not refunded — cancellation only stops future use.
- Endpoint:
POST {BASE_URL}/api/v1/game-gifts/cancel - Security:
X-Public-Key,X-Signature.
Request
{
"operatorId": "MyCasino",
"userId": "player123",
"giftKeys": [
"promo-welcome-2026-04-player123-01",
"promo-welcome-2026-04-player123-02"
]
}
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
operatorId |
String | Yes | Your operator identifier as registered with Game Provider (the same value used as portalName on grant). |
userId |
String | No | Player ID. Optional for the cancel operation itself but recommended for auditing. |
giftKeys[] |
Array of String | Yes | The giftKey values to cancel. |
Response
{
"code": "OK",
"gifts": [
{ "giftKey": "promo-welcome-2026-04-player123-01", "granted": false, "code": "CANCELED" },
{ "giftKey": "promo-welcome-2026-04-player123-02", "granted": false, "code": "CANCELED" }
]
}
granted: false here simply reflects that the gift is no longer playable — not a failure.
3. Gift Lifecycle
Every gift moves through the following states:
| Status | Meaning |
|---|---|
ACTIVE |
Granted, within its activation window, with rounds remaining. Can be consumed by the player. |
COMPLETED |
All quantity rounds have been used. |
CANCELED |
Canceled via POST /api/v1/game-gifts/cancel. No longer playable. |
EXPIRED |
expirationDate has passed. No longer playable. |
Progression: ACTIVE → one of COMPLETED, CANCELED, EXPIRED.
4. How Free Bets Appear in the Wallet API
Once a gift is granted, the player plays rounds as normal. Game Provider detects the eligible gift automatically and signals each free-bet round through your existing Wallet callbacks. You do not need extra endpoints — just handle these action types correctly:
On bet (round start) — POST /withdraw
{
"currency": "USD",
"amount": 0,
"provider": "Game Provider",
"provider_tx_id": "tx-freebet-7001",
"game": "chicken-race",
"action": "FREE_BET",
"action_id": "round-555",
"session_token": "sess-abc-123",
"platform": "desktop",
"user_id": "player123",
"attributes": [
{ "name": "bonus", "value": "freebet" },
{ "name": "createDate", "value": "2026-04-20T14:30:00Z" }
]
}
Rules:
action="FREE_BET".amount=0millis — do not deduct from the real balance.attributescontainsbonus: "freebet".- Return your normal
TransferResponseDTO(acknowledge + current real balance).
On win — POST /deposit
{
"currency": "USD",
"amount": 2500,
"provider": "Game Provider",
"provider_tx_id": "tx-freebet-7002",
"withdraw_provider_tx_id": "tx-freebet-7001",
"game": "chicken-race",
"action": "FREE_BET_WIN",
"action_id": "round-555",
"session_token": "sess-abc-123",
"platform": "desktop",
"user_id": "player123",
"attributes": [
{ "name": "coefficient", "value": "2.50" },
{ "name": "createDate", "value": "2026-04-20T14:30:07Z" }
]
}
Rules:
action="FREE_BET_WIN".amountis the win in millis — credit it to the player's real balance (unless your policy is to credit a bonus sub-wallet; check with your compliance team).withdraw_provider_tx_idlinks to the originalFREE_BETtransaction.
Idempotency and retry semantics are identical to regular BET / WIN — see Wallet API — Idempotency.
5. Error Codes
See Error Handling — Gifts / Free Bets for the full catalog. The codes most commonly returned on grant / cancel are:
| Code | Name | Meaning |
|---|---|---|
10014 |
FAILED_TO_GRANT_GIFT | Grant failed at the gifter service. |
10012 |
FAILED_TO_CANCEL_GIFT | Cancel failed. |
10016 |
FREEBET_NOT_AVAILABLE | No active gift matches the player/game. |
10017 |
INVALID_AMOUNT | betLevel missing or non-positive. |
10024 |
INVALID_GIFTS_LIST | gifts array missing or empty. |
10025 |
INVALID_GIFT_KEY | giftKey missing. |
10026 |
INVALID_GIFT_QUANTITY | quantity ≤ 0. |
10027 |
INVALID_BET_LEVEL | betLevel ≤ 0. |
6. Practical Checklist
Before going live with free bets:
- [ ]
betLevelis sent in millis (no floats, no decimals). - [ ] Every
giftKeyis globally unique (prefix with promo + date + userId + sequence to be safe). - [ ]
activationDate<expirationDate, both in ISO local-datetime format. - [ ] Grant requests are signed with HMAC-SHA256 over the raw body.
- [ ] Your Wallet
withdrawhandler acceptsaction: "FREE_BET"withamount: 0and does not touch the real balance. - [ ] Your Wallet
deposithandler acceptsaction: "FREE_BET_WIN"and credits theamount(in millis) to the player. - [ ] Partial-success responses (
gifts[].granted) are inspected individually. - [ ] Cancel uses
giftKeys[]— not gift IDs or indexes.