Skip to content
Getting started / Data format
Getting started

Data format

The conventions every request and response follows.

  • JSON, Content-Type: application/json, UTF-8. Field names are snake_case.
  • Responses are flat, without an envelope. A success and an error are both top-level objects.
  • Currencies are ISO 4217 codes. A session is one currency from open to close; nothing is converted.
  • Timestamps are ISO 8601 in UTC: 2026-09-29T12:00:00Z.
  • Ids are opaque strings up to 120 characters. player_id is your reference and is never interpreted.
  • Ignore fields you do not know. New fields are added without a version change.
  • A body that is not valid JSON, or a field or query parameter of the wrong JSON type, is refused like any other invalid request: HTTP 422, VALIDATION_FAILED, with the field named in fields (body when the JSON does not parse).

Money

Amounts that move money are decimal strings: "1.50", never 1.5. Decimal point, no thousands separator, in the currency's own precision. Send back what you were sent and do not reformat it.

WhereJSON typeFields
Wallet callbacks and answersstringamount, balance, bonus_amount
Transactions and roundsstringamount
Free spinsstringbet_amount, win_amount, bet-option amounts
Jackpotsnumbertiers[].amount, winners amount
Ratesnumberpercent, from_amount, to_amount
Invoice webhooknumberevery figure: revenue, total, amount, tax_amount…
Parse numbers as decimals
Jackpot amounts, rates and invoice figures are JSON numbers today. They are informational, not wallet movements; read them with a decimal parser rather than a binary float. If they change to strings, it will be announced in the changelog first.

Your wallet must answer balance as a string. A numeric balance cannot be read, and an unreadable answer is treated as no answer: the call is retried and then rolled back.

Game identifiers

A game has two identities, and they travel in different places.

FieldWhereWhat it is
idcatalogue (GET /v1/games)Our id of the title (UUID). It is what you send as game_id to POST /v1/sessions, free spins and demo.
codecatalogueThe provider game code, for display and support.
provider_codecatalogueThe provider, as GET /v1/providers names it.
game_idwallet callbacksThe game provider's code for the round being played, e.g. vs20fruitsw. It is not the catalogue id, and can differ from code.
game_idsfree-spin grant answerGame provider codes, as the series was placed.

Mapping a wallet callback to the catalogue

mapping
GET /v1/games                    →  game.id = "6ddd5f30-0b1c-4c52-9f3e-2a7c1b8e4d10"
POST /v1/sessions { game_id: game.id }
                                 →  session_id = "2222aaaa-…"     store (session_id → game.id)
wallet call  { session_id: "2222aaaa-…", game_id: "vs20fruitsw" }
                                 →  look up session_id  →  game.id

Key your records by session_id. It is on every wallet callback and maps back to the catalogue game ID you launched.

Rate limits

Limits are configured per operator as requests per calendar minute and are given to you with your credentials. The window restarts at the start of each minute and counts only correctly signed requests.

  • Over the limit: HTTP 429, RATE_LIMITED, retryable: true.
  • The answer carries Retry-After: whole seconds until the next minute starts, from 1 to 60. Wait that long, then retry with the same ids.
  • Fetch the catalogue, providers and rates on a schedule and cache them; they change when providers publish, not per player.