SoftAggregator API documentation
Integrate 40,000+ casino games through one seamless-wallet API. This reference covers everything you need to list games, create players, launch games, award free rounds and handle wallet callbacks.
Introduction
The SoftAggregator API uses a seamless wallet model: your platform keeps player balances, and our API calls your callback URL for every balance check, bet and win. All API methods are sent as POST requests with a JSON body to a single endpoint.
Base URL
https://api.softaggregator.com/api/v1
Authentication
Every request includes your api_login and api_password (issued in your operator backend after approval). The method field selects the operation.
{
"api_login": "YOUR_API_LOGIN",
"api_password": "YOUR_API_PASSWORD",
"method": "getGameList"
}
Currencies
Every money method — createPlayer, getGame, getGameDemo and addFreeRounds — accepts an optional currency field (ISO 4217 code, e.g. EUR, USD, BRL, INR, PKR). It sets the currency the player sees in the game — bet limits and balance.
| When | Behaviour |
|---|---|
currency omitted | Your account's default currency is used. |
currency provided | Must be a currency enabled for your account — i.e. supported by the products you have enabled. A currency that is not supported makes the launch fail. |
| Per player | A player's currency is set the first time the player is created and does not change afterwards. Use a distinct user_username if you need the same person in another currency. |
Wallet callbacks (balance / debit / credit) carry the same currency, and amount is always in that currency's minor units (e.g. 2.50 → 250). The currencies available to you are provisioned by SoftAggregator — contact support or @mentionso to enable a new currency on your account.
getCurrencies below.getCurrenciesGet your currencies
Returns the currencies enabled for your account, so you can pick the right currency value programmatically instead of hard-coding it.
POST /api/v1
{ "api_login":"...", "api_password":"...", "method":"getCurrencies" }
→ {
"error": 0,
"response": {
"default": "PKR", // send this on getGame / createPlayer (or omit to use it)
"currencies": ["PKR","EUR"], // currencies your account may use
"settlement": "EUR" // currency your account is billed in
}
}
getGameListGet game list
Returns all games available to you. Use each game's id_hash when launching a game.
POST /api/v1
{ "api_login": "...", "api_password": "...", "method": "getGameList" }
→ {
"error": 0,
"response": [
{
"id": 483,
"name": "Game Name",
"type": "video-slots",
"category": "pragmaticplay",
"id_hash": "provider/GameName",
"freerounds_supported": true,
"play_for_fun_supported": true,
"image": "https://.../GameName.webp"
}
]
}
createPlayerCreate player
Creates (or ensures) a player on the system before launching a game.
{ "api_login":"...", "api_password":"...", "method":"createPlayer",
"user_username":"player123", "user_password":"secret", "currency":"EUR" }
→ { "error": 0, "response": { ... } }
getGameLaunch game
Returns the URL to load the game in an iframe. Use the id_hash from getGameList as gameid.
| Field | Description |
|---|---|
user_username | Player username |
user_password | Player password |
gameid | Game id_hash |
lang | Language code, e.g. en |
currency | Optional — player currency (see Currencies). Defaults to your account currency. |
homeurl | Return URL after the player exits |
play_for_fun | Optional — demo mode |
{ "api_login":"...", "api_password":"...", "method":"getGame",
"user_username":"player123", "user_password":"secret",
"gameid":"provider/GameName", "lang":"en", "currency":"EUR",
"homeurl":"https://yourcasino.com" }
→ { "error": 0, "response": "https://game-launch-url..." }
method: "getGameDemo" with the same parameters.addFreeRoundsFree rounds
Award free spins on a supported game (freerounds_supported: true in the game list).
{ "api_login":"...", "api_password":"...", "method":"addFreeRounds",
"user_username":"player123", "user_password":"secret",
"gameid":"provider/GameName", "freespins":10, "bet_level":0,
"valid_days":7, "currency":"EUR" }
Use getFreeRounds to list and deleteFreeRounds to remove them.
getPlayerHistoryPlayer history
Returns the round history of one of your players, newest first. One entry per game round (all legs of a round are merged). Amounts are integers in cents, in the currency the round was played in.
{ "api_login":"...", "api_password":"...", "method":"getPlayerHistory",
"user_username":"player123",
"limit":50, "offset":0,
"date_from":"2026-08-01 00:00:00", "date_to":"2026-08-01 23:59:59",
"gameid":"x6046f4988155b46", "round_id":"..." }
Only user_username is required. limit defaults to 50 (max 500); gameid is the id_hash from getGameList; date_from/date_to are UTC.
{ "error":0, "response":{
"user_username":"player123", "total":128, "limit":50, "offset":0,
"rounds":[
{ "round_id":"88c6807b55e7434c3e00aa50dc82240e",
"gameid":"x6046f4988155b46", "game_name":"Gates of Olympus 1000",
"currency":"USD", "bet":40, "win":58, "net":18,
"legs":2, "rolled_back":false,
"started_at":"2026-08-01 16:10:15", "ended_at":"2026-08-01 16:10:24" } ] } }
| Field | Meaning |
|---|---|
total | Rounds matching the filter (for paging), not the number returned |
bet / win | Total wagered / paid for the round, in cents |
net | win - bet: negative = player lost the round |
legs | Wallet movements merged into this round |
rolled_back | true if the round was cancelled/refunded |
Wallet callbacks
We call your callback URL (set in your operator backend) for every player balance change. Callbacks are sent as GET requests. Your endpoint must always return HTTP 200; communicate errors only via the JSON body. Balances are always integers in cents (e.g. €2.50 → 250).
action: balance
Sent at the start of a session to read the player's balance.
GET {your_callback}?username=player123¤cy=EUR&action=balance
&call_id=...×tamp=...&key=...
← { "error": 0, "balance": 250 }
action: debit / credit
debit subtracts a bet; credit adds a win. call_id is the unique transaction id — use it to de-duplicate. If funds are insufficient on a debit, return error: 1 with the current balance.
GET {your_callback}?username=player123¤cy=EUR&action=debit
&amount=100&type=bet&round_id=...&game_id=provider/GameName
&call_id=...×tamp=...&rb=0&key=...
← { "error": 0, "balance": 150 }
Two rules your handler must follow.
- Never reject a callback because of
type. Branch onactiononly.typeis informational and its set of values grows as we add providers — treat an unknown value as a normal bet or win. - A
creditcan arrive with no matchingdebit. Free spins, bonus rounds and jackpot payouts are wins withamountonly — there is no bet to match them against. De-duplicate oncall_idalone; requiring a prior debit means your players never get paid for free-spin wins.
| Field | Description |
|---|---|
amount | Amount in cents |
action | debit | credit | balance |
type | Informational, never reject on it. bet on a debit, win on a credit; bonus_fs marks a free spin (nothing to deduct on debit). Other values may appear. |
call_id | Unique transaction id (de-dup) |
round_id | Game round id |
game_id | Game id_hash |
rb | 1 = rollback (process like a normal debit/credit) |
Signature validation
Every callback carries timestamp and key. Validate that the timestamp is within 30 seconds and that the key matches:
key = md5(timestamp + your_salt_key)
Your salt_key is shown in your operator backend. If validation fails, return { "error": 2, "balance": 0 }.
Error codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Insufficient balance (return current balance) |
2 | Processing error / invalid signature / player not found |
Need help integrating? Contact us on Telegram @mentionso or email [email protected].