Skip to content

Open app

How a round works

Every game round flows through three actors: your operator backend, Aggregator.gg, and the game provider. The player sees only the game iframe. You own the wallet: Aggregator.gg never holds player funds, so paid bets and wins settle in your ledger. Grant-funded bets preserve cash, and refunds reverse a recorded debit once.

Player Operator Aggregator.gg Provider
| | | |
|-- open game --->| | |
| |-- POST /v1/sessions -->| |
| | (Idempotency-Key) |-- create session ->|
| | |<-- session URL ----|
| |<-- session_id, --------| |
| | game_url | |
|<-- redirect ----| | |
|-- plays the game ------------------------------------------->|
| | |<-- bet ------------|
| |<-- POST callback_url --| |
| | (bet, X-SIGNATURE) | |
| |--- 200 { balance } --->|-- confirmed ------>|
| | |<-- win ------------|
| |<-- POST callback_url --| |
| | (win, X-SIGNATURE) | |
| |--- 200 { balance } --->|-- confirmed ------>|
|-- closes game ->| | |

Three rules govern the whole flow:

  1. You own the wallet. Paid bets debit and wins credit your ledger; free bets do not debit cash.
  2. Callbacks are synchronous. The provider waits for your response before showing the result to the player. Your callback endpoint must respond within 5 seconds.
  3. Idempotency is required on both legs. Session and free-round creation require a stable Idempotency-Key; callbacks can repeat and use a separate scoped identity: trusted integration/organization context, provider_code and transaction_id.

Create a session with POST /v1/sessions. Persist a unique AGGREGATOR_OPERATION_ID for this launch and reuse it with the same body only on retries. Send the game, player, balance, currency, and country; platforms also select their brand:

Terminal window
curl -X POST "https://api.aggregator.gg/v1/sessions" <<EOF \
--header @- \
-H "Idempotency-Key: ${AGGREGATOR_OPERATION_ID:?Set a persisted unique ID for this launch; reuse only for its retries}" \
-H "Content-Type: application/json" \
-d '{
"game_id": "d4f7a2b1-3c8e-4f5a-9b6d-1e2f3a4b5c6d",
"player_id": "player_42",
"balance": 10000,
"currency": "EUR",
"country": "DE",
"lang": "de",
"return_url": "https://your-casino.com/lobby"
}'
Authorization: Bearer ${AGGREGATOR_API_KEY:?Set the issued key in the protected environment}
EOF
{
"session_id": "8c8e8c8e-8c8e-4c8e-8c8e-8c8e8c8e8c8e",
"game_url": "https://games.aggregator.gg/launch/8c8e8c8e-8c8e-4c8e-8c8e-8c8e8c8e8c8e",
"provider_session_uid": "tl_session_abc",
"provider_code": "truelabs"
}

Details that matter here:

  • game_id is the Aggregator.gg catalog UUID, the id returned by GET /v1/games. It is not the provider’s own game code.
  • balance is an integer in the currency’s minor units: 10000 means 100.00 EUR. Session balance, normalized callback amount and callback response balance use minor units. Free-round bet_amount and stake metadata have their own documented representation; do not apply a universal conversion across endpoints.
  • game_url is a private session credential. Open it promptly and keep it out of logs or shared caches. Expiry and reuse behavior depend on the provider.
  • country drives jurisdiction rules. A game blocked in the player’s country returns 403.

Step check: the response carries session_id and game_url, and opening the private game_url in a browser loads the expected game. Do not infer wallet acceptance from the page rendering.

Each spin triggers HMAC-signed callbacks to the callback URL you configured in the cabinet. A bet arrives first; when the spin resolves with a payout, a win follows.

For every callback you receive:

  1. Verify the X-SIGNATURE header against the raw request body. See Request signatures.
  2. Deduplicate by trusted integration/organization context, provider_code and transaction_id; replay the stored original status and body for that identity. Commit movement and response atomically before success.
  3. Branch on transaction_type, not on action (a provider-specific label):
transaction_type Meaning Your action
bet Player placed a bet Debit a paid bet; preserve cash when is_free: true
win Player won Credit amount to the player’s balance
refund A previous bet was reversed Reverse the original recorded debit once; a free bet has no cash debit to refund
  1. Respond 200 with a JSON body carrying balance and currency (both required), echoing player_id.

The callback amount and your response balance are integers in the same minor units: a bet of 500 at balance 10000 returns balance 9500 with no unit conversion anywhere. For a bet the player cannot afford, respond 402; the bet is not placed.

Step check: after one spin, your ledger records the expected paid/free movements without duplicates, and your endpoint answered each callback within 5 seconds.

Some zero cash legs are completed inside Aggregator.gg without a wallet callback. This is not a rule to discard every zero amount: free-round wins can be delivered with amount: 0, including win-only settlement. Reconcile each recorded leg against its expected movement and delivery evidence; finished and transaction IDs have different roles.

Sessions need no explicit close call. The session stays open for replays and expires automatically; an expired session returns 410 (E3002 session_expired), and you create a new one with POST /v1/sessions.

Step check: GET /v1/transactions lists every leg of your test rounds, and the expected paid/free/reversal effects agree with your ledger. Platforms arrange brand-level evidence separately; the machine transactions feed is not a consolidated brand feed.

  • Timeout, connection failure or HTTP 5xx: eligible delivery paths can retry within a bounded budget. Preserve the same scoped transaction identity. See Callbacks.
  • HTTP 3xx/4xx: terminal delivery responses; fix the cause and investigate safe recovery. A recognized 402 is a business decline.
  • Malformed HTTP 200 or another 2xx: delivery is unknown; automatic redelivery stops. Reconcile the original outcome before recovery.
  • Callbacks arrive out of order: validate trusted session and player context and the provider-specific lifecycle; do not assume one bet/win pair or credit arbitrary unmatched events. Free-round win-only settlement is explicitly supported.
  • Launch outcome is unclear: retry the same session operation key and body within the response-cache contract. Reconcile before making a fresh operation; creating another session is not proof that the first failed.