Skip to content

Open app

Getting started

Start with the product explanation, then register, integrate, verify, buy a package, confirm credit and launch. The operator controls registration, keys, tests, payment and Go live; MCP can explain the next step and read available evidence.

The six integration steps below verify an API key that works, a game that launches, a wallet callback that settles real money, and the evidence that it all holds together. Implementation time depends on your wallet and available access; production hardening and internal review are additional work.

The division of labour is fixed: you own the wallet, Aggregator.gg normalizes every provider protocol into one session API and one callback shape, and the provider runs the game. The player only ever sees the game iframe.

You need:

  • An operator account at app.aggregator.gg. KYB verification does not have to be finished before you start: you can mint a key and work through this guide while the file is open. See API keys
  • A server that can receive HTTPS callbacks on a public URL
  • A durable wallet store with an atomic unique identity combining trusted integration/organization context, provider_code and transaction_id
  • Familiarity with REST APIs and callback patterns

Platform accounts: create the first brand and verify its catalog before step 1. Use sub_operator_ref on the supported catalog, session and free-rounds calls, and confirm the shared platform wallet with support if its editor is unavailable. Platform accounts lists the exact endpoint rules and reconciliation limits. The examples below are for an ordinary operator; do not run them unchanged under a platform key.

Before any of that, prove the API is up: curl -sS https://api.aggregator.gg/health answers {"status": "ok"} and needs no API key.

Step Outcome You know it is done when
1. API key Authenticated access GET /v1/games returns 200
2. Catalog A launchable game id You hold a catalog UUID for a game in your player’s currency
3. Demo session Game on screen, no money game_url opens the game in free-play mode
4. Wallet callback Signed money path Your endpoint verifies, settles, and answers within 5 seconds
5. Real session Controlled round within an approved budget Bet and win callbacks settle in your ledger
6. Proof Readiness evidence Probes pass and GET /v1/transactions reconciles with your wallet

In the cabinet, open API Keys and create your agg_ key. It is shown once, at creation time. New test keys are not issued. This key has a stored live environment, so a test session can move money; possession of a key alone is not test or launch approval. See API keys. Your callback secret is a separate credential that you will set yourself under API -> Callbacks in step 4.

The human loads both values into protected environment variables or a secret manager, never source control, chat or browser-side code. Keep shell tracing off; the examples pass $AGGREGATOR_API_KEY through stdin rather than curl arguments. Same-user access to process environments remains a risk:

Terminal window
curl -s "https://api.aggregator.gg/v1/games?per_page=1" <<EOF \
--header @-
Authorization: Bearer ${AGGREGATOR_API_KEY:?Set the issued key in the protected environment}
EOF

Step check: the response is 200 with a games array. A 401 means the key is wrong or was not sent as a Bearer token; the rejection arrives as a flat body, {"error": "invalid_token", "message": "API key authentication failed"}, not as the coded envelope other failures use. See Errors.

Terminal window
curl -X GET "https://api.aggregator.gg/v1/games?per_page=5" <<EOF \
--header @-
Authorization: Bearer ${AGGREGATOR_API_KEY:?Set the issued key in the protected environment}
EOF
{
"games": [
{
"id": "d4f7a2b1-3c8e-4f5a-9b6d-1e2f3a4b5c6d",
"name": "Book of Huli",
"provider_code": "truelabs",
"game_type": "slots",
"rtp": 96.33,
"volatility": "high",
"has_mobile": true,
"has_desktop": true,
"has_demo": true,
"thumbnail_url": "https://cdn.aggregator.gg/thumbs/book-of-huli.jpg",
"blocked_countries": ["US", "GB"],
"features": ["free_spins", "bonus_buy"],
"supported_currencies": ["USD", "EUR"]
}
],
"total": 98,
"page": 1,
"per_page": 5
}

The id field is the Aggregator.gg catalog UUID, and it is the only game identifier you ever send when launching. Do not send a provider’s own game code.

Filter by currency up front so players only see games their wallet currency can open. The filter applies before pagination, so total reflects it:

Terminal window
curl -X GET "https://api.aggregator.gg/v1/games?currency=EUR" <<EOF \
--header @-
Authorization: Bearer ${AGGREGATOR_API_KEY:?Set the issued key in the protected environment}
EOF

You can also filter by provider, game type, volatility, RTP range, features, and full-text search.

Step check: you hold the catalog id of a game whose supported_currencies includes your player’s currency and whose blocked_countries excludes their country.

A demo session puts the game on screen with no wallet involvement: no debits, no bet or win callbacks, no impact on welcome credits.

Terminal window
curl -X POST "https://api.aggregator.gg/v1/demo-sessions" <<EOF \
--header @- \
-H "Content-Type: application/json" \
-d '{"game_id": "d4f7a2b1-3c8e-4f5a-9b6d-1e2f3a4b5c6d"}'
Authorization: Bearer ${AGGREGATOR_API_KEY:?Set the issued key in the protected environment}
EOF

The response carries a game_url that opens the game in free-play mode. Treat this as a session credential: open it promptly, keep it out of logs and shared caches, and follow the provider’s reuse and expiry behavior. A universal single-use guarantee is not part of this API contract.

Step check: the game renders and spins in free-play mode, and no callback ever arrives at your server.

In the cabinet, open API -> Callbacks and save two things: one public HTTPS URL, and the callback secret you choose (minimum 16 characters; the integration wizard can generate one). The cabinet stores the secret encrypted and never displays it again, only that one is set, so put it in your secret manager as you save it. One callback URL applies across all providers. From now on, every bet and win in a real session arrives there as a signed POST:

{
"action": "BET-WIN",
"transaction_type": "bet",
"transaction_id": "tx_bet_001",
"amount": 500,
"currency": "EUR",
"player_id": "player_42",
"provider_code": "truelabs",
"game": "book-of-huli-96",
"game_id": "d4f7a2b1-3c8e-4f5a-9b6d-1e2f3a4b5c6d",
"round_id": "round_abc",
"finished": false,
"session_id": "8c8e8c8e-8c8e-4c8e-8c8e-8c8e8c8e8c8e"
}

Your handler must, in order:

  1. Verify the X-SIGNATURE header against the raw request body before parsing anything. See Request signatures.
  2. Deduplicate by trusted integration/organization context, provider_code and transaction_id. Replay the stored original status and body for a duplicate of that complete identity.
  3. Branch on transaction_type and is_free, not on action: debit a paid bet, preserve cash on a free bet, credit a win, and reverse only a recorded debit once for a refund. Commit the movement and its replayable response atomically before success.
  4. Respond within 5 seconds with 200 and a JSON body carrying balance and currency (both required), echoing player_id:
{
"balance": 9500,
"currency": "EUR",
"player_id": "player_42"
}

amount and balance are integers in the currency’s minor units and share one denomination: a bet of 500 (5.00 EUR) against a balance of 10000 returns 9500, with no unit conversion anywhere. For a bet the player cannot afford, respond 402; the bet is not placed. A 500 from you triggers retries. The full contract, including retry backoff, lives in Callbacks.

Step check: your endpoint is reachable over public HTTPS, rejects a tampered body with a 4xx, and answers a valid callback with 200, balance, and currency in under 5 seconds.

Real sessions move real money, so session creation and free-round issuance carry an Idempotency-Key header that stays stable across retries. Generate and persist one unique AGGREGATOR_OPERATION_ID before this operation, then reuse it and the identical body only for retries. See Idempotency.

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"
}

balance is an integer in minor units: 10000 means 100.00 EUR. country drives jurisdiction rules; a blocked game returns 403. return_url is where the player lands on closing the game. Open game_url promptly; keep the URL private and follow provider expiry/reuse rules.

Before the human runs this test, confirm the organization has access to the game, sufficient credits, a controlled wallet/test player and explicit spending limits. A welcome grant may help only if it is actually present; there is no universal free sandbox promise. If access or budget is missing, stop and resolve it in the cabinet. Early purchase is optional and does not count as a passed test. See Environments.

Step check: one spin produces a signed bet callback and, on a payout, a win callback, both settled in your ledger; repeating the session request with the same Idempotency-Key returns the identical response with X-Idempotent-Replayed: true.

Evidence beats confidence. Three checks turn “it seems to work” into proof:

  1. Run the cabinet readiness check. The Run check button fires an advisory probe suite at your callback URL: accepted bets, wins, refunds, free-round legs, duplicates, and rejection cases. Probes are real callbacks with the production payload and signature contract plus an X-Aggregator-Readiness: probe header, and they can move money on the player they name, so point them at a dedicated test player. The current advisory probe accepts a broader 2xx range, but actual wallet delivery requires HTTP 200 and the strict response contract. Passing the probe does not validate that distinction. Probe rejection cases (bad signature, zero or negative amount on a bet, unsupported currency, non-JSON content type) expect a 4xx, because a 5xx is retried rather than refused.
  2. Tamper and replay against your own endpoint. Change one byte of a captured callback and confirm a 4xx. Re-send an unchanged one and confirm your original response replays with no wallet movement.
  3. Reconcile. After a batch of spins, fetch GET /v1/transactions and match every bet and win against your wallet ledger. Some zero cash legs settle internally and have no wallet movement; free-round zero wins can still be delivered. Reconcile by provider, scoped transaction identity and expected movement, including grant-funded bets and reversals. An empty API page or a completed status alone is not proof of complete reconciliation. Platform accounts need the brand-level evidence described in Platform accounts. Investigate unexplained differences before customer traffic.

Step check: every probe scenario passes or is explained, tamper and replay tests behave, and the transactions API matches your ledger exactly. Readiness results are advisory: retain session, callback and ledger evidence from the ordinary API-key path. Demo or a green badge alone does not prove settlement. A human reviews the evidence and applicable backend conditions before go-live.

Platform credits pay for access to game supply; the player balance belongs to your wallet. A prepaid spin package funds platform usage and is not a player deposit. Check current offers and payment methods in the existing cabinet checkout.

After the integration test, the human chooses and pays for a package, confirms the server reports a paid purchase and its matching credited balance, then reviews Go-live before opening traffic. A quote, a click, a transaction hash or a welcome/admin grant is not a completed paid purchase. Treat pending, failed/rejected and unknown states separately; return to the cabinet to check the authoritative status. Do not assume retries continue after closing checkout.

Buying earlier remains optional. This recommended sequence adds no billing or KYB gate. Welcome credits, if present, still require the same controlled wallet verification as other live traffic; demo sessions do not prove that money path.

Business errors use one envelope. Match on recognized code values; log only HTTP status and a fixed allowlist of codes. Never log raw bodies, messages, headers or secrets. Auth failures are the exception: a 401 currently answers with a flat {"error": "invalid_token", "message": "API key authentication failed"} body, no code field, so match those on the HTTP status. See Errors.

{
"error": {
"code": "E2001",
"type": "game_not_found",
"message": "Game Not Found",
"details": {}
}
}

The codes you are most likely to meet on this track:

Code HTTP Meaning What to do
E5002 401 API key invalid (delivered as the flat auth body above) Check the Bearer header and the key value
E2001 404 Game not found Use the catalog id from GET /v1/games
E2003 403 Game blocked in the player’s jurisdiction Respect blocked_countries; do not offer the game
E3004 403 Player self-excluded Do not allow play; this is a regulatory requirement
E4001 402 Insufficient balance: on a callback, the player’s; on POST /v1/sessions, your organization’s credits Callback: decline the bet and return the current balance. Session launch: top up credits in the cabinet
E9001 429 Rate limited Back off and respect the X-RateLimit-* headers

Use bounded backoff for eligible transient errors while preserving the same operation key and body. Handle 429 and in-progress idempotency separately; reconcile ambiguous money outcomes before creating a new operation. The complete catalogue lives in the error reference.