Gamification

VeliGames Gamification adds tournaments and missions to your games. Progress is tracked from existing bet/win events, and rewards are delivered through your seamless wallet.

Use the supplied widget for the standard integration. The Gamification API is available for custom interfaces.

Widget integration

  1. Ask your VeliGames representative to enable gamification for your brand.

  2. Prepare reward handling in your wallet.

  3. Configure colours and fonts in Gamification → Settings in the backoffice.

  4. Use the existing start-game integration and open startGameUrl exactly as returned, including its query string. For enabled brands, it opens the game with the widget.

  5. Verify participation, progress and reward delivery with a test campaign. Include out-of-session rewards and duplicate wallet notifications in testing.

The supplied widget handles the gamification API calls and player session. No additional login or progress event feed is required. During a gamification API outage, the game must remain usable with no widget visible; verify this with the widget version supplied to your brand.

Receiving rewards

Implement /promo-win to receive reward notifications. Tournament and mission rewards carry campaignType TOURNAMENT or MISSION and their own transactionId.

  • MONEY_REWARD: cash reward.

  • CASINO_BONUS: award the specified bonus template; the callback amount is 0.

  • FREE_BET_WIN: winnings from an internally assigned free bet, not the initial free-bet assignment.

Follow the Wallet API’s field requirements and make crediting idempotent on transactionId.

Without /promo-win, reward settlement falls back to a zero-amount bet followed by /win. Rewards can arrive after the game session ends, so your wallet must support out-of-session settlement.

Gamification API reference

API host: https://VELIGAMES_API_URL. Use the host supplied for your environment.

Authentication

Send requests from your backend with the signature header, using the operator credentials and signature construction already used by your integration.

Request

Signed payload and player identity

GET

Sign the complete query, including brandId and all supplied parameters.

POST opt-in / opt-out

Sign the JSON body, including brandId and playerId.

POST claim / claim-all

Sign the JSON body, including brandId. Pass playerId in the query.

Omit unused optional fields. For this API, null values are omitted from the signature string.

Tournament lists and leaderboards can be requested without playerId for a logged-out catalogue; the request still requires a signature. Missions, player position, participation and claims require a player.

Pagination and filters

page starts at 1 and defaults to 1. size defaults to 10, with a maximum of 20 for tournament/mission lists and 100 for leaderboards.

Paginated responses contain rows, size, page, totalElements, totalPages, first and last. Empty results return rows: [] and at least one page.

Repeat query keys for array filters, for example statuses=ACTIVE&statuses=SCHEDULED.

Tournaments

API Method: tournaments

Lists tournaments and the player’s participation state.

Path:

/gamification-api/tournaments/public/tournaments

HTTP Method:

GET

Query parameters

Parameter

Type

Requirement / description

brandId

string

Required. Brand identifier.

playerId

string

Optional. Player whose participation to include. Without a player, optedIn is false.

statuses

string[]

Optional. SCHEDULED, ACTIVE, FINISHED or CANCELED.

templateIds / tournamentIds

UUID[]

Optional. Restrict to templates or occurrences.

currencies

string[]

Optional. Currency filter.

from / to

date-time

Optional. Tournament schedule filters.

languageCode

string

Optional. Request localized content.

size / page

integer

Optional. Size 1–20; page ≥ 1. Defaults: 10 and 1.

Response — HTTP 200

Returns a paginated list of tournament objects:

Row field

Type

Description

id / templateId

string

Occurrence and template identifiers.

status

string

SCHEDULED, ACTIVE, FINISHED or CANCELED.

startAt / endAt / createdAt

date-time

Tournament window and creation time.

optedIn

boolean

Whether the player participates.

template

object

optIn, optOut and nullable priority.

filter

object

Included/excluded games, providers and categories, plus country rules. A game reference has id and providerId.

content

object / null

Localized name, descriptionTitle, description, bgImageUrl, prizePoolDescription, faqTitle and faq. Can be null when content is unavailable.

Illustrative tournament list
{
  "size": 10, "page": 1, "totalElements": 1,
  "totalPages": 1, "first": true, "last": true,
  "rows": [{
    "id": "11111111-1111-4111-8111-111111111111",
    "templateId": "33333333-3333-4333-8333-333333333333",
    "status": "ACTIVE",
    "startAt": "2026-10-23T00:00:00.000Z",
    "endAt": "2026-10-24T00:00:00.000Z",
    "createdAt": "2026-10-22T10:00:00.000Z",
    "optedIn": false,
    "template": {"optIn": true, "optOut": true, "priority": 1},
    "filter": {
      "include": {"games": [], "providers": [], "categories": []},
      "exclude": {"games": [], "providers": [], "categories": []},
      "countries": {"op": "exclude", "values": []}
    },
    "content": {
      "name": "Daily Spin Race", "descriptionTitle": null,
      "description": "Compete for the top of the leaderboard.",
      "bgImageUrl": null, "prizePoolDescription": "EUR 1,000",
      "faqTitle": null, "faq": []
    }
  }]
}

API Method: leaderboard

Returns the tournament leaderboard.

Path:

/gamification-api/tournaments/public/leaderboard

HTTP Method:

GET

Query parameters

Parameter

Type

Requirement / description

tournamentId

UUID

Required. Tournament occurrence.

brandId

string

Required. Brand identifier.

languageCode

string

Optional. Language for prize display content.

size / page

integer

Optional. Size 1–100; page ≥ 1. Defaults: 10 and 1.

Response — HTTP 200

Each row contains playerId, brandId, place, points, rewardsGranted, rewardsGrantedAt, rewardName and rewardImageUrl. The last three fields are nullable. totalElements is the leaderboard capacity; empty ranks have empty player/brand values and zero points.

{
  "size": 1, "page": 1, "totalElements": 10,
  "totalPages": 10, "first": true, "last": false,
  "rows": [{
    "playerId": "player-1", "brandId": "yourBrand", "place": 1,
    "points": 9743.5, "rewardsGranted": false,
    "rewardsGrantedAt": null, "rewardName": "EUR 100",
    "rewardImageUrl": null
  }]
}

API Method: leaderboard/player

Returns the player’s rank, score and earned rewards.

Path:

/gamification-api/tournaments/public/leaderboard/player

HTTP Method:

GET

Query parameters

Parameter

Type

Requirement / description

tournamentId

UUID

Required. Tournament occurrence.

brandId

string

Required. Brand identifier.

playerId

string

Required. Player whose position to read.

languageCode

string

Optional. Language for prize display content.

Response — HTTP 200

The object contains place, points, nullable rewardName / rewardImageUrl, and rewards (the shared reward model). An unranked player returns:

{"place":0,"points":0,"rewardName":null,"rewardImageUrl":null,"rewards":[]}

API Method: opt-in (tournaments)

Enrolls the player in an open tournament.

Path:

/gamification-api/tournaments/public/opt-in

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

tournamentId

UUID

Required. Tournament occurrence/run.

brandId

string

Required. Brand identifier.

playerId

string

Required. Player whose participation to change.

Response — HTTP 200

{"success":true}

The response may also contain an optional message string.

API Method: opt-out (tournaments)

Opts the player out of an open tournament. Returns OPT_OUT_DISABLED if the campaign does not allow opting out.

Path:

/gamification-api/tournaments/public/opt-out

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

tournamentId

UUID

Required. Tournament occurrence/run.

brandId

string

Required. Brand identifier.

playerId

string

Required. Player whose participation to change.

Response — HTTP 200

{"success":true}

The response may also contain an optional message string.

API Method: claim (tournaments)

Queues one earned reward for processing.

Required query parameter: playerId (string). Sign the JSON body below.

Path:

/gamification-api/tournaments/public/claim

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

tournamentId

UUID

Required. The tournament occurrence/run.

rewardId

UUID

Required. Returned reward id with claimable: true and status: PENDING.

brandId

string

Required. Brand identifier.

Response — HTTP 200

Returns the claim response.

API Method: claim-all (tournaments)

Queues all pending claimable rewards for this player in this tournament. It does not claim rewards across other tournaments.

Required query parameter: playerId (string). Sign the JSON body below.

Path:

/gamification-api/tournaments/public/claim-all

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

tournamentId

UUID

Required. The tournament occurrence/run.

brandId

string

Required. Brand identifier.

Response — HTTP 200

Returns the claim response.

Missions

API Method: missions

Lists missions with the player’s step progress and completion rewards.

Path:

/gamification-api/missions/public/missions

HTTP Method:

GET

Query parameters

Parameter

Type

Requirement / description

brandId

string

Required. Brand identifier.

playerId

string

Required. Player whose missions and progress to read.

currency

string

Optional. Player currency for per-currency targets and reward amounts.

languageCode

string

Optional. Language for localized display text.

size / page

integer

Optional. Size 1–20; page ≥ 1. Defaults: 10 and 1.

Response — HTTP 200

Row field

Type

Description

id / templateId

UUID

Mission run and template identifiers.

name / description

string

Localized display content.

imageUrl

string / null

Mission image.

status

string

NOT_STARTED, IN_PROGRESS, OPTED_OUT, COMPLETED or EXPIRED.

startAt / endAt

date-time

Mission window.

optIn

boolean

Whether joining is required.

startedAt / completedAt

date-time / null

Player start/completion times.

steps

object[]

Ordered steps: id, name, position, target, progress, status (LOCKED, IN_PROGRESS or COMPLETED), and rewards.

rewards

object[]

Mission completion rewards. Step and completion rewards use the shared reward model.

Illustrative mission list
{
  "size": 10, "page": 1, "totalElements": 1,
  "totalPages": 1, "first": true, "last": true,
  "rows": [{
    "id": "44444444-4444-4444-8444-444444444444",
    "templateId": "55555555-5555-4555-8555-555555555555",
    "name": "Daily Wins", "description": "Complete the daily challenge",
    "imageUrl": null, "status": "COMPLETED", "optIn": true,
    "startAt": "2026-10-23T00:00:00.000Z",
    "endAt": "2026-10-24T00:00:00.000Z",
    "startedAt": "2026-10-23T08:00:00.000Z",
    "completedAt": "2026-10-23T09:00:00.000Z",
    "steps": [{
      "id": "66666666-6666-4666-8666-666666666666",
      "name": "Win once", "position": 1, "target": 1,
      "progress": 1, "status": "COMPLETED", "rewards": [{
        "id": "77777777-7777-4777-8777-777777777777",
        "type": "MONEY", "amount": 10, "currency": "EUR",
        "points": null, "claimable": true, "status": "PENDING"
      }]
    }],
    "rewards": []
  }]
}

API Method: opt-in (missions)

Enrolls the player in an open mission.

Path:

/gamification-api/missions/public/opt-in

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

missionId

UUID

Required. Mission occurrence/run.

brandId

string

Required. Brand identifier.

playerId

string

Required. Include the player in the signed body.

Response — HTTP 200

{"success":true}

When optIn is false, players are enrolled through eligible gameplay.

API Method: opt-out (missions)

Opts the player out of an open mission. Returns OPT_OUT_DISABLED if the campaign does not allow opting out.

Path:

/gamification-api/missions/public/opt-out

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

missionId

UUID

Required. Mission occurrence/run.

brandId

string

Required. Brand identifier.

playerId

string

Required. Include the player in the signed body.

Response — HTTP 200

{"success":true}

API Method: claim (missions)

Queues one earned reward for processing.

Required query parameter: playerId (string). Sign the JSON body below.

Path:

/gamification-api/missions/public/claim

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

missionId

UUID

Required. The mission occurrence/run.

rewardId

UUID

Required. Returned reward id with claimable: true and status: PENDING.

brandId

string

Required. Brand identifier.

Response — HTTP 200

Returns the claim response.

API Method: claim-all (missions)

Queues all pending claimable rewards for this player in this mission. It does not claim rewards across other missions.

Required query parameter: playerId (string). Sign the JSON body below.

Path:

/gamification-api/missions/public/claim-all

HTTP Method:

POST

Request body

Parameter

Type

Requirement / description

missionId

UUID

Required. The mission occurrence/run.

brandId

string

Required. Brand identifier.

Response — HTTP 200

Returns the claim response.

Widget theme

API Method: theme

Returns the saved brand theme for your custom interface. Configure the theme in the backoffice; the supplied widget applies it automatically.

Path:

/gamification-api/settings/public/theme

HTTP Method:

GET

Query parameters

Parameter

Type

Requirement / description

brandId

string

Required. Include in the signed query.

Response — HTTP 200

Returns the saved theme, or null if none is configured. Apply defaults for missing palette values.

Field

Type

Description

brandId

string

Brand associated with the theme.

style

object

Saved hex colours: primary, optional gradient end primaryTo, background, text, success and error. Missing entries need client defaults.

fontFamily

string / null

CSS font-family stack.

fontUrl

string / null

Google Fonts stylesheet URL (fonts.googleapis.com).

{
  "brandId": "yourBrand",
  "style": {
    "primary": "#FFC24D", "background": "#0d0d12",
    "text": "#edeff2", "success": "#4ade80", "error": "#ff5a5a"
  },
  "fontFamily": "Lexend, sans-serif",
  "fontUrl": "https://fonts.googleapis.com/css2?family=Lexend:wght@400;600;800&display=swap"
}

Reward model and claims

Mission step/completion rewards and tournament player rewards use this model:

Field

Type

Description

id

UUID

Reward identifier to pass as rewardId.

type

string

FREE_BET, CASINO_BONUS, MONEY or XP.

amount / currency

number / null; string / null

Resolved reward amount and currency, when available.

points

number / null

XP points, when applicable.

claimable

boolean

Whether the player must claim the earned reward.

status

string

Reward state, described below.

Status

Meaning

NOT_EARNED

Mission reward not earned yet.

PENDING

Earned, not yet granted. A claim is required when claimable is true.

CLAIMED

Claim recorded; fulfillment is processing.

GRANTED

Reward granted. Free-bet winnings are settled separately.

FAILED

Fulfillment failed. Eligible retries are handled by VeliGames, not another player claim.

Only offer a claim for claimable: true and status: PENDING. Rewards with claimable: false are processed automatically. Tournament reward records do not use NOT_EARNED.

Claim response

{
  "claimed": ["22222222-2222-4222-8222-222222222222"],
  "status": "CLAIMED"
}

claimed contains the IDs newly queued by the request. If none match an eligible pending reward, the response is:

{"claimed": [], "status": "NOTHING_TO_CLAIM"}

Claims are idempotent: repeating the same request does not queue a reward twice. CLAIMED confirms acceptance, not payout. Refresh the player’s rewards to check fulfillment. NOTHING_TO_CLAIM can mean already claimed, already granted or no matching reward owned by the player.

Claim request example

Sign the JSON body below and supply playerId in the query. Replace the example IDs and HMAC_FOR_BODY with your values.

curl -X POST \
  'https://VELIGAMES_API_URL/gamification-api/tournaments/public/claim?playerId=player-1' \
  -H 'signature: OPERATOR_ID:HMAC_FOR_BODY' \
  -H 'Content-Type: application/json' \
  -d '{
    "brandId": "yourBrand",
    "tournamentId": "11111111-1111-4111-8111-111111111111",
    "rewardId": "22222222-2222-4222-8222-222222222222"
  }'

For missions, use /missions/public/claim and missionId. For claim-all, omit rewardId. Recompute the signature for the body you send.

Errors

Error responses use application/problem+json:

{"title": "Bad Request", "status": 400, "detail": "PLAYER_ID_REQUIRED"}

HTTP

Detail

Meaning

400

validation failed

Invalid parameters. errors[] identifies the field in location and its validation message.

400

PLAYER_ID_REQUIRED

Player identity is missing from the required query or body.

403

Missing or invalid signature

Check the credentials and complete signed payload.

404

MISSION_NOT_FOUND

Mission run unavailable.

422

TOURNAMENT_CONFIG_NOT_FOUND

Tournament configuration unavailable.

422

TOURNAMENT_FINISHED / MISSION_FINISHED

Participation can no longer be changed.

422

INCORRECT_BRAND / OPT_OUT_DISABLED

Brand not eligible, or opting out is disabled.

500

INTERNAL_ERROR

Request could not be completed. After an uncertain claim, refresh reward status before retrying.