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.
Before you start
Section titled “Before you start”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_codeandtransaction_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.
The integration path
Section titled “The integration path”| 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 |
Step 1: Create and store your API key
Section titled “Step 1: Create and store your API key”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:
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}EOFStep 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.
Step 2: List the game catalog
Section titled “Step 2: List the game catalog”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:
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}EOFYou 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.
Step 3: Launch a demo session
Section titled “Step 3: Launch a demo session”A demo session puts the game on screen with no wallet involvement: no debits, no bet or win callbacks, no impact on welcome credits.
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}EOFThe 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.
Step 4: Build the wallet callback
Section titled “Step 4: Build the wallet callback”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:
- Verify the
X-SIGNATUREheader against the raw request body before parsing anything. See Request signatures. - Deduplicate by trusted integration/organization context,
provider_codeandtransaction_id. Replay the stored original status and body for a duplicate of that complete identity. - Branch on
transaction_typeandis_free, not onaction: 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. - Respond within 5 seconds with
200and a JSON body carryingbalanceandcurrency(both required), echoingplayer_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.
Step 5: Launch a real session
Section titled “Step 5: Launch a real session”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.
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.
Step 6: Prove your integration is ready
Section titled “Step 6: Prove your integration is ready”Evidence beats confidence. Three checks turn “it seems to work” into proof:
- 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: probeheader, and they can move money on the player they name, so point them at a dedicated test player. The current advisory probe accepts a broader2xxrange, 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 a4xx, because a5xxis retried rather than refused. - 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. - Reconcile. After a batch of spins, fetch
GET /v1/transactionsand match everybetandwinagainst 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.
How billing works
Section titled “How billing works”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.
Error handling
Section titled “Error handling”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.