The Eva platform, or simply Eva, is a platform that aggregates the content of various game suppliers and provides a single API for external operators.
With it, you can access a broad catalog of products.

This document contains a description and examples of the API provided by Eva as a content aggregator to make the integration process easier

To integrate own platform via Eva operator should:

  • Provide uri of the service which is going to be responsible for handling wallet transactions

  • Provide credentials (username & password) → see Authorization header at API Reference section

  • Implement mandatory mappings described in API Reference section

1. Non-functional requirements

Here are described non-functional requirements that the operator’s wallet must follow:

  • Compatibility

Only HTTPS communication is supported.

The wallet must be forward-compatible with the all possible API changes and extensions.
This includes additional JSON fields, additional headers.

Eva does not guarantee any data that is not specified in this API and the wallet’s behavior must not depend on any other parameters (Eg: X-Forwarded-Host, X-Forwarded-Proto headers).
* The only exception is the HTTP Protocol requirements, eg: Host header

  • Security
    The wallet must implement these rules:

  • Authentication

Eva uses basic authentication.
Credentials must be encoded at the wallet side.
Technical team must use 1-time sharing tools (Intuitive Password, Privnote, OneTimeNote).

  • IPs whitelisting

Wallet must be protected with the IP whitelist

In case of failure against these rules, the corresponding error must be returned.
It is also highly recommended not to expose API implementation details, the HTTP status code will be enough

  • Performance

The wallet must be highly performant and maintain low latency to ensure real-time responsiveness critical to the player experience.
Any delay in loading balances or processing transactions, must be minimized to prevent a negative impact on user engagement.

Satisfactory values:

P95 percentile

Requests per second Response Time

< 1000

< 40 ms

1k - 2k

< 80 ms

> 2k

< 350 ms

P99 percentile

Requests per second Response Time

< 1000

< 60 ms

1k - 2k

< 200 ms

> 2k

< 450 ms

2. General API sequence

The following diagram illustrates the flow of information between the player’s browser, operator, and Eva

eva platform flow

3. Game Launch

3.1. Overview

The Eva Platform provides a unified launcher URL for operators that works for all games across all providers.
The operator navigates a window to our launcher, and then Eva redirects the window to game server of the provider.

Handling this redirection flow and ensuring proper content delivery to the player is the responsibility of the operator.

The structure for the final launch URL is as follows:

https://<eva_launcher_url>?<query_parameters>

where:

  • eva_launcher_url is the base URL for the Eva launcher, which will be provided to you during the integration phase.

  • query_parameters are the query parameters required to launch a specific game.
    The parameters are detailed below.

Query Parameter Description Type Notes

channel

Launch channel

Enum

Available values: desktop, mobile

gameId

Game identifier

String

Game lobbyId provided by the Eva Platform

language

Optional
The desired language of the game UI in ISO-639-2 format

String(2)

The absence of this parameter will trigger the game launch using the default language

lobbyUrl

URL where the player should be redirected upon clicking the Home button inside the game UI

String

Must be URL encoded

partnerKey

Partner key

String

A unique key for the partner business unit, generated by the Eva Platform.
It will be sent as a header in wallet callbacks

sessionToken

Optional
Player session token.
Supported characters as specified in The "URL and Filename safe" Base 64 Alphabet

String (max 124 characters)

It will be sent as json field in some wallet callbacks.
The absence of this parameter will trigger the game launch in DEMO mode

3.2. Examples

Real mode:

https://some-eva-host.com/v0/casino/games/launch?
    gameId=cool-virtual-product
    &channel=mobile
    &partnerKey=example
    &sessionToken=J7Qjpo4_vkzv8FEwC-Tw7J2YB1w5dZzpu1p6M1ij6nPc_YCQpyNOcwuregUGT6Svm16lWnmyZ
    &language=it
    &lobbyUrl=https%3A%2F%2Fsome-operator-lobby.com%2Fredirect%2Fhome%3Fid%3DOTV6pW%2BjErGq

Demo mode:

https://some-eva-host.com/v0/casino/games/launch?
    gameId=another-virtual-product
    &channel=desktop
    &partnerKey=example
    &lobbyUrl=https%3A%2F%2Fsome-operator-lobby.com%2Fredirect%2Fhome%3Fid%3DOTV6pW%2BjErGq

4. Wallet Integration

4.1. Key Concepts

4.1.1. Round

The casino logic is primarily centered around the concept of rounds.

  • A casino transaction is always initiated by the provider.

  • As the initiator, the provider is responsible for both finalizing the processing and confirming the success of the transaction.

A round can exist in one of two states:

  • Open - it means that additional transactions can still be sent to it.

  • Closed - it means the event associated with the round has already concluded. Any transaction attempting to be processed in a closed round should be rejected.

Scenarios in which the above rules may be violated are described in sections Wallet-Controlled Transaction Scenarios and Special Cases Based on Provider-Specific Logic.

4.1.2. Types of Transactions Within a Round

  • Bet: A financial transaction where funds are deducted from the player’s account. This occurs when the player places a bet.

  • Win: A financial transaction where funds are credited to the player’s account. This takes place when the player wins a game or event, resulting in a payout.

  • Refund: A financial transaction where funds are credited to the player’s account, typically under specific conditions such as canceled bets, errors, or other predefined circumstances that require reimbursement.

Providers have mechanism for sending retries for failed transaction requests:

  • Win requests are retried until they are successfully processed.

  • If an error is returned while processing a bet, the provider generates a refund request, as the status of the bet is uncertain. The provider aims to refund any funds that may have been deducted from the player’s account.

4.2. Wallet Responsibility Definition

The primary responsibility of casino platform, and by extension, each wallet operating at the casino platform level, is to validate casino transactions.

This validation must align with the entire product logic, account for corner cases, and address potential fraud risks.

The wallet is responsible for determining whether a transaction should be processed based on the casino domain logic.

4.2.1. Wallet-Controlled Transaction Scenarios

The wallet is the only system fully responsible for financial losses in the event of transaction failures. Providers do not guarantee that failures will not occur on their side; therefore, the wallet must be protected against such risks.

Based on prior experience, the following common cases occur frequently. The responsibility for handling these cases rests entirely with the wallet:

  • Refund before bet (inverted refund).

  • Refund after a failed bet (depending on the error, the wallet decides whether to process the refund or not).

  • Bet to a closed round.

  • Win to a closed round.

  • Canceling a bet after a win.

  • Bet to a refunded round.

  • Win to a refunded round.

  • Win without a bet.

4.2.2. Special Cases Based on Provider-Specific Logic

There are also edge cases that are technically invalid but are considered a normal flow for some providers due to their specific business logic. These providers request that such scenarios be allowed. This logic should also be embedded in the wallet, which determines what is valid and what is not.

Therefore, as a separate recommendation, these strategies should only be allowed or denied on a per-provider basis:

  • AllowMultipleBets – More than one bet can occur in a round.

  • AllowMultipleWins – More than one win can occur in a round.

  • AllowMultipleRefunds – More than one refund occur in a round.

  • IsWinWithoutBetAllowed – A win without a bet is allowed in a round.

  • AllowPostCloseWin – Allow or deny processing a win that is sent after the round has been closed.

  • AllowPostCloseBet – Allow or deny processing a bet that is sent after the round has been closed.

4.3. API Reference

  • All transaction amounts & player’s balances are represented in minor units
    This means that cents value is passed (e.g. "main": 123, "currency": "USD" indicates that the player’s main balance is $1.23)

  • All transaction requests must be idempotent
    This requires the Operator to ensure that a request with the same details (especially the transactionId) is not processed more than once, while the response must be consistent across all duplicate requests.

  • In case of any exceptional situation, an appropriate error code must be set.
    Refer to the Error Handling section for more details.

  • All parameters described are mandatory, unless noted as optional.
    If a value is optional, a corresponding note will be provided.

Each request from the Eva Platform is sent to the mapping of the URI provided.
For example, if the URI is https://operator-uri.com/api/v1, then the following set of mappings is used:

https://operator-uri.com/api/v1/players/accounts/:playerId?providerId=:provider
https://operator-uri.com/api/v1/players/sessions/:sessionToken?providerId=:provider
https://operator-uri.com/api/v1/transactions/bet
https://operator-uri.com/api/v1/transactions/win
https://operator-uri.com/api/v1/transactions/refund
https://operator-uri.com/api/v1/transactions/promoWin
https://operator-uri.com/api/v1/transactions/tournamentWin

Each request from the Eva Platform contains such mandatory headers:

Header Value Description

Accept

application/json

Specifies the content type of the response body

Authorization

Basic :value

Base64-encoded username:password value for authentication

Content-Type

application/json

Indicates the content type of the request body

X-Partner-Key

example

A unique key for the partner business unit, generated by the Eva Platform

4.3.1. Player Info by ID

This method retrieves information about a player (excluding balance) using the player’s identifier.

Request Example
GET /players/accounts/:playerId?providerId=:example-provider HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Parameter Type Description

playerId

Path parameter

Player’s identifier

providerId

Query parameter

The game provider for which the request is being made

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 122

{
  "country" : "UA",
  "currency" : "USD",
  "displayName" : "example-display-name",
  "playerId" : "example-player-id"
}
Field Type Description

country

String

Player’s country in ISO-3166-1 alpha-2 format

currency

String

Player’s currency in ISO-4217-3 format

displayName

String

Player’s display name

playerId

String

Unique player identifier

4.3.2. Player Info by session token

This method is used to get the player’s information by session token.

Request Example
GET /players/sessions/:sessionToken?providerId=:example-provider HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Parameter Type Description

sessionToken

Path parameter

Player’s session token

providerId

Query parameter

Game provider for which the request is performed

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 200

{
  "balance" : {
    "bonus" : 500,
    "locked" : 200,
    "main" : 1000
  },
  "country" : "UA",
  "currency" : "USD",
  "displayName" : "example-display-name",
  "playerId" : "example-player-id"
}
Field Type Description

balance

Object

Nested object carrying player’s balance details

balance.bonus

Long

Amount of money that the player received from bonus campaigns

balance.locked

Long

Amount of money that the player deposited to participate in deposit campaigns

balance.main

Long

Player’s main balance

country

String

Player’s country in ISO-3166-1 alpha-2 format

currency

String

Player’s currency in ISO-4217-3 format

displayName

String

Player’s display name

playerId

String (max 28 characters)

Unique player identifier - supported characters from The "URL and Filename safe" Base 64 Alphabet

4.3.3. Player Session Token by player details

This method is used to initiate player’s session on partner’s platfrom by the details passed in request.

  • It’s mandatory to implement and support it only at STAGE environment - so it must be missing at PROD

  • This method is intended only for TESTING purposes

Request Example
POST /players/sessions?providerId=:example-provider HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Content-Length: 92

{
  "currency" : "USD",
  "gameId" : "example-game-id",
  "playerId" : "example-player-id"
}
Parameter Type Description

providerId

Query parameter

Game provider for which the request is performed

currency

String

Currency to initiate the session

gameId

String

Game identifier to initiate the session

playerId

String (max 28 characters)

Unique player identifier - supported characters from The "URL and Filename safe" Base 64 Alphabet

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 63

{
  "sessionToken" : "QIy9BrNamCthaTuyXJeKC-zv6lwtLyqNVMEsBq"
}
Field Type Description

sessionToken

String

Player’s session token

4.3.4. Bet Transaction

The bet (debit) method is called when funds should be deducted from the player’s balance.

  • The wallet must guarantee that the player’s session is valid during bet transaction processing.

  • Bets placed outside an active session must be rejected.

Request Example
POST /transactions/bet HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Content-Length: 370

{
  "amount" : 123,
  "currency" : "USD",
  "gameId" : "example-game-id",
  "playerId" : "example-player-id",
  "provider" : "example-provider",
  "reason" : "bet",
  "roundClosed" : false,
  "roundId" : "example-round-id",
  "sessionToken" : "QIy9BrNamCthaTuyXJeKC-zv6lwtLyqNVMEsBq",
  "sideSplit" : {
    "base" : 100,
    "side" : 23
  },
  "txId" : "example-tx-id"
}
Field Type Description

amount

Long

Amount of the transaction in the currency’s minor units

currency

String

Currency of this transaction

gameId

String

Game identifier where the bet was placed

playerId

String

Player to whom the transaction is related

provider

String

Game provider for which the request is performed

reason

String

Reason for this transaction. Possible values: bet, refund_of_win

roundClosed

Boolean

Identifies whether the game round is finished

roundId

String

Game round identifier

sessionToken

String

Player’s session token

txId

String

Unique transaction identifier

Optional sideSplit

Object

Contains base and side amounts for live casino side bets

sideSplit.base

Long

Amount of the main bet

sideSplit.side

Long

Amount of the side bet

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 393

{
  "at" : "2023-04-06T11:47:52.859062Z",
  "balance" : {
    "bonus" : 500,
    "locked" : 200,
    "main" : 1000
  },
  "currency" : "USD",
  "tx" : {
    "at" : "2023-04-06T11:47:52.859062Z",
    "id" : "example-tx-id",
    "processed" : false,
    "processedTxId" : "example-processed-tx-id",
    "txAmountDetails" : {
      "bonus" : 20,
      "locked" : 10,
      "main" : 30
    }
  }
}
Field Type Description

at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

balance

Object

Nested object carrying player’s balance details

balance.bonus

Long

Player’s relevant bonus balance

balance.locked

Long

Player’s relevant locked balance

balance.main

Long

Player’s relevant main balance

currency

String

Player’s currency in ISO-4217-3 format

tx

Object

Nested object carrying transaction details

tx.at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

tx.id

String

Transaction identifier from the request

tx.processed

Boolean

Identifies whether the transaction was already processed before this request

tx.processedTxId

String

Transaction identifier on the operator’s side

tx.txAmountDetails

Object

Nested object carrying details about balance changes by this transaction

tx.txAmountDetails.bonus

Long

Amount of money deducted from the bonus balance

tx.txAmountDetails.locked

Long

Amount of money deducted from the locked balance

tx.txAmountDetails.main

Long

Amount of money deducted from the main balance

4.3.5. Win Transaction

The win (credit) method is called when funds should be added to the player’s balance.

Request Example
POST /transactions/win HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Content-Length: 357

{
  "amount" : 123,
  "currency" : "USD",
  "freeSpinData" : {
    "freeSpin" : "no"
  },
  "gameId" : "example-game-id",
  "playerId" : "example-player-id",
  "provider" : "example-provider",
  "reason" : "win",
  "roundClosed" : false,
  "roundId" : "example-round-id",
  "sideSplit" : {
    "base" : 100,
    "side" : 23
  },
  "txId" : "example-tx-id"
}
Field Type Description

amount

Long

Amount of the transaction in the currency’s minor units

currency

String

Currency of this transaction

freeSpinData

Object

Nested object carrying free spin details

freeSpinData.freeSpin

String

Identifies whether this transaction is related to a free spin campaign.
Possible values: no, regular (intermediate free spin), last (the last free spin related to the player’s bonus)

gameId

String

Game identifier where the bet was placed

playerId

String

Player to whom the transaction relates

provider

String

Game provider for which the request is performed

reason

String

Reason this transaction was committed.
Possible values: win, jackpot, jackpot_non_progressive, refund_of_bet

roundClosed

Boolean

Identifies whether the game round has finished

roundId

String

Game round identifier

txId

String

Unique transaction identifier

Optional sideSplit

Object

Contains base and side winnings for live casino side bets

sideSplit.base

Long

Amount of the main win

sideSplit.side

Long

Amount of the side win

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 393

{
  "at" : "2023-04-06T11:47:52.859062Z",
  "balance" : {
    "bonus" : 500,
    "locked" : 200,
    "main" : 1000
  },
  "currency" : "USD",
  "tx" : {
    "at" : "2023-04-06T11:47:52.859062Z",
    "id" : "example-tx-id",
    "processed" : false,
    "processedTxId" : "example-processed-tx-id",
    "txAmountDetails" : {
      "bonus" : 20,
      "locked" : 10,
      "main" : 30
    }
  }
}
Field Type Description

at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

balance

Object

Nested object carrying the player’s balance details

balance.bonus

Long

Player’s relevant bonus balance

balance.locked

Long

Player’s relevant locked balance

balance.main

Long

Player’s relevant main balance

currency

String

Player’s currency in ISO-4217-3 format

tx

Object

Nested object carrying transaction details

tx.at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

tx.id

String

Transaction identifier from the request

tx.processed

Boolean

Identifies whether the transaction had already been processed before this request

tx.processedTxId

String

Transaction identifier on the operator’s side

tx.txAmountDetails

Object

Nested object carrying details about balance changes by this transaction

tx.txAmountDetails.bonus

Long

Amount of money deducted from the bonus balance

tx.txAmountDetails.locked

Long

Amount of money deducted from the locked balance

tx.txAmountDetails.main

Long

Amount of money deducted from the main balance

4.3.6. Refund Transaction

When the previous bet transaction needs to be rejected, the refund method is called, returning the processed bet amount to the player’s balance.

Each refund request must include the transaction ID of the bet for which the refund is intended. This ensures that every refund request is linked to the specific bet it corresponds to, enabling proper tracking and processing.

  • The transaction ID allows the wallet to accurately associate the refund request with the corresponding bet, ensuring appropriate handling based on the provider’s specifications.

In certain cases, the refund amount may not be specified in the refund request. When this occurs, the provider expects the wallet to calculate the refund amount based on the bet details.

  • Since the refund request always contains the bet ID, the wallet is responsible for retrieving the relevant bet amount, if necessary, to process the refund appropriately.

Request Example
POST /transactions/refund HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Content-Length: 363

{
  "amount" : 123,
  "betTxId" : "example-tx-id",
  "currency" : "USD",
  "gameId" : "example-game-id",
  "playerId" : "example-player-id",
  "provider" : "example-provider",
  "reason" : "refund_of_bet",
  "refundTxId" : "example-tx-id_refund",
  "roundClosed" : false,
  "roundId" : "example-round-id",
  "sideSplit" : {
    "base" : 100,
    "side" : 23
  }
}
Field Type Description

amount

Long

Amount of the transaction in the currency’s minor units

currency

String

Currency of this transaction

gameId

String

Game identifier where the bet was placed

playerId

String

Player to whom the transaction relates

provider

String

Game provider for which the request is performed

reason

String

Reason this transaction was committed. Possible values: refund_of_bet

roundClosed

Boolean

Identifies whether the game round has finished

roundId

String

Game round identifier

betTxId

String

TxId of the bet transaction to be refunded

refundTxId

String

Unique refund transaction identifier

Optional sideSplit

Object

Contains base and side amounts for live casino side bets cancel

sideSplit.base

Long

Amount of the main cancel

sideSplit.side

Long

Amount of the side cancel

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 393

{
  "at" : "2023-04-06T11:47:52.859062Z",
  "balance" : {
    "bonus" : 500,
    "locked" : 200,
    "main" : 1000
  },
  "currency" : "USD",
  "tx" : {
    "at" : "2023-04-06T11:47:52.859062Z",
    "id" : "example-tx-id",
    "processed" : false,
    "processedTxId" : "example-processed-tx-id",
    "txAmountDetails" : {
      "bonus" : 20,
      "locked" : 10,
      "main" : 30
    }
  }
}
Field Type Description

at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

balance

Object

Nested object carrying the player’s balance details

balance.bonus

Long

Player’s relevant bonus balance

balance.locked

Long

Player’s relevant locked balance

balance.main

Long

Player’s relevant main balance

currency

String

Player’s currency in ISO-4217-3 format

tx

Object

Nested object carrying transaction details

tx.at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

tx.id

String

Transaction identifier from the request

tx.processed

Boolean

Identifies whether the transaction had already been processed before this request

tx.processedTxId

String

Transaction identifier on the operator’s side

tx.txAmountDetails

Object

Nested object carrying details about balance changes by this transaction

tx.txAmountDetails.bonus

Long

Amount of money deducted from the bonus balance

tx.txAmountDetails.locked

Long

Amount of money deducted from the locked balance

tx.txAmountDetails.main

Long

Amount of money deducted from the main balance

4.3.7. Promo Win Transaction

When a player receives some promo offers, the promoWin method is called to add funds to the player’s balance.

Request Example
POST /transactions/promoWin HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Content-Length: 167

{
  "amount" : 123,
  "currency" : "USD",
  "playerId" : "example-player-id",
  "provider" : "example-provider",
  "reason" : "promo_win",
  "txId" : "example-tx-id"
}
Field Type Description

playerId

String

Player to whom the transaction relates

provider

String

Game provider for which the request is performed

reason

String

Reason this transaction was committed. Possible values: promo_win

txId

String

Unique transaction identifier

amount

Long

Amount of the transaction in the currency’s minor units

currency

String

Currency of this transaction

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 393

{
  "at" : "2023-04-06T11:47:52.859062Z",
  "balance" : {
    "bonus" : 500,
    "locked" : 200,
    "main" : 1000
  },
  "currency" : "USD",
  "tx" : {
    "at" : "2023-04-06T11:47:52.859062Z",
    "id" : "example-tx-id",
    "processed" : false,
    "processedTxId" : "example-processed-tx-id",
    "txAmountDetails" : {
      "bonus" : 20,
      "locked" : 10,
      "main" : 30
    }
  }
}
Field Type Description

at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

balance

Object

Nested object carrying the player’s balance details

balance.bonus

Long

Player’s relevant bonus balance

balance.locked

Long

Player’s relevant locked balance

balance.main

Long

Player’s relevant main balance

currency

String

Player’s currency in ISO-4217-3 format

tx

Object

Nested object carrying transaction details

tx.at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

tx.id

String

Transaction identifier from the request

tx.processed

Boolean

Identifies whether the transaction had already been processed before this request

tx.processedTxId

String

Transaction identifier on the operator’s side

tx.txAmountDetails

Object

Nested object carrying details about balance changes by this transaction

tx.txAmountDetails.bonus

Long

Amount of money deducted from the bonus balance

tx.txAmountDetails.locked

Long

Amount of money deducted from the locked balance

tx.txAmountDetails.main

Long

Amount of money deducted from the main balance

4.3.8. Tournament Win Transaction

When a player succeeds in tournaments, the tournamentWin method is called to add funds to the player’s balance.

Request Example
POST /transactions/tournamentWin HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcm5hbWUtYWJjOnBhc3N3b3JkLWFiYw==
Content-Type: application/json
X-Partner-Key: example-key
Content-Length: 212

{
  "amount" : 123,
  "currency" : "USD",
  "playerId" : "example-player-id",
  "provider" : "example-provider",
  "reason" : "tournament",
  "tournamentId" : "example-tournament-id",
  "txId" : "example-tx-id"
}
Field Type Description

playerId

String

Player to whom the transaction relates

provider

String

Game provider for which the request is performed

reason

String

Reason this transaction was committed. Possible values: tournament

tournamentId

String

Unique tournament identifier

txId

String

Unique transaction identifier

amount

Long

Amount of the transaction in the currency’s minor units

currency

String

Currency of this transaction

Response Example
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 393

{
  "at" : "2023-04-06T11:47:52.859062Z",
  "balance" : {
    "bonus" : 500,
    "locked" : 200,
    "main" : 1000
  },
  "currency" : "USD",
  "tx" : {
    "at" : "2023-04-06T11:47:52.859062Z",
    "id" : "example-tx-id",
    "processed" : false,
    "processedTxId" : "example-processed-tx-id",
    "txAmountDetails" : {
      "bonus" : 20,
      "locked" : 10,
      "main" : 30
    }
  }
}
Field Type Description

at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

balance

Object

Nested object carrying the player’s balance details

balance.bonus

Long

Player’s relevant bonus balance

balance.locked

Long

Player’s relevant locked balance

balance.main

Long

Player’s relevant main balance

currency

String

Player’s currency in ISO-4217-3 format

tx

Object

Nested object carrying transaction details

tx.at

String

Timestamp indicating when the transaction was processed (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

tx.id

String

Transaction identifier from the request

tx.processed

Boolean

Identifies whether the transaction had already been processed before this request

tx.processedTxId

String

Transaction identifier on the operator’s side

tx.txAmountDetails

Object

Nested object carrying details about balance changes by this transaction

tx.txAmountDetails.bonus

Long

Amount of money deducted from the bonus balance

tx.txAmountDetails.locked

Long

Amount of money deducted from the locked balance

tx.txAmountDetails.main

Long

Amount of money deducted from the main balance

5. Error Handling

In case any error occurs on the Operator’s side while handling the corresponding request, Eva Platform expects a response indicating the error with such a structure and an appropriate HTTP status:

HTTP/1.1 400 Bad Request
Content-type: application/json; charset=UTF-8
Content-Length: 132

{
  "at" : "2023-04-06T11:47:52.859062Z",
  "errorCode" : "error.player.session-expired",
  "message" : "Session token is expired"
}
Field Type Description

errorCode

String

Error code identifier. A list of error codes is provided in the section below

message

String

Human-readable error message

at

String

Time when the error occurred (YYYY-MM-DDThh:mm:ss.SSSSSSZ ISO 8601 format)

5.1. Error Codes

Code Status code Description

error.player.incorrect-currency

422

Returned when the player’s currency is invalid

error.player.insufficient-balance

422

Returned when there is not enough balance to perform an action. Applicable for bet call

error.player.locked

422

Returned when the player has restrictions on the operator’s platform

error.player.not-found

422

Returned when the player is not found on the operator’s platform

error.player.session-expired

422

Returned when the session token passed in the request is expired or incorrect. Applicable for playerInfo & bet calls

error.request.validation-failed

400

Returned when validation of the request body data fails

error.system.unexpected

500

Returned when an unexpected internal error occurs on the operator’s platform

error.transaction.casino-logic-validation-failed

422

Returned for unexpected casino game flow (e.g., win without bet, refund for a round with win)
We do not recommend using this code. It is best to consult the integration team before using it

error.transaction.target-tx-not-found

422

Returned for an unknown transaction. Applicable for refund call

6. Data API

6.1. Authentication

6.1.1. Overview

To ensure security and control access to the Data API, authorization is performed via the OAuth 2.0 protocol using the "Client Credentials" scheme.

6.1.2. Retrieving token

This method allows client applications to obtain an access token using their credentials (client_id and client_secret).

POST /v0/management/token HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
X-Partner-Key: example-key

grant_type=client_credentials&client_id=client&client_secret=secret
Body Parameter Description Type

grant_type

Should be client_credentials

String

client_id

Credentials provided during integration phase for each partner unit

String

client_secret

Credentials provided during integration phase for each partner unit

String

Response example:
HTTP/1.1 200 OK
Content-type: application/json; charset=UTF-8
Content-Length: 95

{
  "access_token": "2YotnFZFEjr1zCsicMWpAA",
  "token_type": "Bearer",
  "expires_in": 3600
}

After successful authentication you must use the provided token to authorize on the Data API using the following format:

Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

6.1.3. Error handling

If an error occurs while attempting to retrieve a new access token, the operator can expect a response indicating the error with such structure:

HTTP/1.1 401 Unauthorized
Content-type: application/json; charset=UTF-8
Content-Length: 86

{
  "error" : "unauthorized_client",
  "error_description" : "Invalid client secret"
}

If authorization fails when trying to access a secured resource, the operator can expect a response indicating the authorization error with structure described in the OAuth 2.0 protocol

Examples:
HTTP/1.1 401 Unauthorized
Content-Length: 0
WWW-Authenticate: Bearer error="invalid_token", error_description="Principal isn't resolved.", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"

or

HTTP/1.1 403 Forbidden
Content-Length: 0
WWW-Authenticate: Bearer error="insufficient_scope", error_description="Partner key isn't allowed.", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1", scope="partner_data"

6.2. Game details

6.2.1. Overview

The Data API provides access to game-related data for external operators.
It allows retrieval of game information, filtering by various criteria passed as query parameters

The structure for the final URL is as follows:

https://<eva_target_data_api_url>?page={page}&size={size}&<query_parameters>

where:

  • eva_target_data_api_url is the base URL for the Eva Data API handler.
    This will be provided during the integration phase.

  • query_parameters are the query parameters for additional filtering.

  • The page and size query parameters control pagination:

    • page specifies the page number.

    • size determines the number of items per page.

The following table describes the query parameters accepted by the API:

Query Parameter Description Type Notes

size

Number of records per page

Integer

Limited by value configured on Eva Platform side

page

Optional
Page number for pagination

Integer

Defaults to 0 if not specified

gameId

Optional
The game identifier accessible from the lobby

String

Unique game identifier at lobby

walletId

Optional
Wallet identifier associated with transactions

String

Game identifier at wallet

productType

Optional
Game type

Enum

Available values: slots, virtual-sports, tv-games, live-casino, instant-games, bingo

translationKey

Optional
Key for retrieving the game title translation

String

Game title translation key

gameProvider

Optional
The game provider related to the game(s).

String

Identifier of the game’s provider

channel

Optional
Target channel where the game is available

Enum

Distribution channel for the game. Available values include mobile, desktop, omni

isFreeSpinsAvailable

Optional
Availability of free spins

Boolean

Filters games based on the availability of free spins.

The response includes pagination details and the resulting items, allowing operators to navigate through the data efficiently.

The following table describes the response fields:

Field Description Type

currentPage

Integer

Current page

totalItems

Integer

Total number of items

totalPages

Integer

Total number of pages

items

Array of objects

Carrying game items filtered by query parameters passed

items[i].gameId

String

Unique game identifier at lobby

items[i].walletId

String

Game identifier at wallet

items[i].productType

Enum

Possible values: slots, virtual-sports, tv-games, live-casino, instant-games, bingo

items[i].translationKey

String

Game title translation

items[i].gameProvider

String

Game provider identifier

items[i].channel

Enum

Distribution channel for the game. Possible values include mobile, desktop, omni

items[i].dealerLanguage

Nullable String

Dealer language

items[i].imageUrl

Nullable String

URL pointing to image file of the game

items[i].isDemoModeAvailable

Boolean

Indicates if demo mode (not using real balance) is available on game launch

items[i].isFreeSpinsAvailable

Boolean

Indicates if free spins are available

items[i].isActive

Boolean

Indicates if the game is active

6.2.2. Examples

Request example:
GET /v0/management/games?size=5&page=0&gameId=game-identifier&walletId=wallet-identifier&translationKey=GameName&gameProvider=game-provider&channel=desktop&isFreeSpinsAvailable=false HTTP/1.1
Accept: application/json
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
X-Partner-Key: example
Response example:
{
  "currentPage": 0,
  "totalItems": 1,
  "totalPages": 1,
  "items": [
    {
      "gameId": "game-identifier",
      "walletId": "wallet-identifier",
      "productType": "slots",
      "translationKey": "GameName",
      "gameProvider": "game-provider",
      "channel": "desktop",
      "dealerLanguage": "UK",
      "imageUrl": "https://image-url.com/some/path/image.png",
      "isDemoModeAvailable": true,
      "isFreeSpinsAvailable": false,
      "isActive": true
    }
  ]
}

6.3. Game Images Management

6.3.1. Overview

Default images may not always satisfy all the needs, so the operator can use the methods described below to manage custom images.

6.3.2. Upload Custom Game Image

This method allows you to upload a custom image for a specific game by its ID.
The image will become available globally through its unique URL returned in the response.
The response from the Game details method will also include the new URL for the custom image.

This method overwrites the image only for the specific partner unit.
Request:
PUT /v0/management/games/{gameId}/images HTTP/1.1
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Content-Type: multipart/form-data; boundary=1234567
X-Partner-Key: example

--1234567
Content-Disposition: form-data; name="image"; filename="image.png"

<image content>
--1234567
Content-Disposition: form-data; name="fileName"

image.png
--1234567--

Where:

  • image is the required part containing the image content itself

  • fileName is the required part containing the image file name, since the filename attribute in the Content-Disposition is optional

Response:
HTTP/1.1 200 OK
Content-Length: 45

https://testhost.tech/games/image123.png

6.3.3. Delete Custom Image

This method allows you to delete a custom image for a specific game by its ID.
The response from the Game details method will now revert to the URL for the default image, if available.

The image will no longer be accessible via the previously generated URL.
Request:
DELETE /v0/management/games/{gameId}/images HTTP/1.1
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
X-Partner-Key: example
Response:
HTTP/1.1 200 OK
Content-Length: 0

6.4. Free spins

6.4.1. Overview

This section of the API is designed for managing free spin campaigns and bonuses.
It includes endpoints to create campaign, grant bonus to player and cancel bonus.
These operations are crucial for promotional activities in gaming platforms.

All requests to the related free-spin endpoints require authentication.
Consumers must include the following mandatory headers in each request:

  • X-Partner-Key - A unique identifier for the partner.

  • X-Provider-Id - Identifies the game provider.
    This ensures that the appropriate provider’s contract is associated with the partner key provided.

Free spin endpoints are idempotent.

When a request is made to the free spin endpoint with same parameters (ones acting as idempotent markers), subsequent requests with the exact same parameters are not executed within underlying services.
Instead, they confirm that the original campaign or bonus already exists (or already cancelled) and return a successful response without any further modifications.

6.4.2. Creating campaign

This endpoint is used to create a new free spin campaign.
The campaign details must be specified in the request body.

Request example:
POST /v0/management/bonuses/free-spins/campaigns HTTP/1.1
Accept: application/json
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Content-Type: application/json
X-Partner-Key: example
X-Provider-Id: provider

{
  "gameId": "provider-game-id",
  "campaignId": "campaign-id",
  "spins": 10,
  "campaignStartDate": "2020-12-03T10:15:30.675220736Z",
  "campaignEndDate": "2020-12-04T10:15:30Z",
  "spinsExpirationDuration": 68004,
  "betAmounts": {
    "EUR": 9000,
    "USD": 10000
  }
}
Property Name Description Type Notes

gameId

Game identifier on provider’s side

String

Id of the game which the free spin campaign is available for

campaignId

Unique identifier of the free spin campaign on the operator’s side

String

Unique identifier for the free spin campaign, acting as an idempotent marker

spins

Amount of free spins

Integer

Number of free spins offered in the campaign for a player

campaignStartDate

The timestamp of campaign start date (ISO 8601)

String

Timestamp marking the start of the free spin campaign

campaignEndDate

The timestamp of campaign end date (ISO 8601)

String

Timestamp marking the end of the free spin campaign

spinsExpirationDuration

Time in millisecond for free spins

Long

Time in milliseconds during which the player can use the free spins from the campaign.
This duration begins when the player is added to the free spin campaign within its active period (between campaignStartDate and campaignEndDate). Free spins expire once this duration elapses. The expiration date might exceed campaignEndDate; in this case, the player should be allowed to complete their free spins execution until the spinsExpirationDuration period ends.

betAmounts

Map of currency and amount of bet

Map<String, Long>

Specifies the currencies available in the free spin campaign and their corresponding bet amounts in minor units

Response example:
{
  "campaignId": "campaign-id",
  "externalCampaignId": "campaign-id-on-providers-side"
}
Property Name Description Type Notes

campaignId

Unique identifier of the free spin campaign on the operator’s side

String

The same id as the one provided in the request, serving as confirmation that the campaign has been successfully created

externalCampaignId

Unique identifier of the free spin campaign on the provider’s side

String

Actual identifier that was used (or was assigned by provider) to create campaign

6.4.3. Awarding bonus

This endpoint is used to award a free spin bonus to a player.
The details associated with the bonus, related campaign and player identifier must be included in the request body.

Request example:
POST /v0/management/bonuses/free-spins/grant HTTP/1.1
Accept: application/json
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Content-Type: application/json
X-Partner-Key: example
X-Provider-Id: provider

{
  "campaignId": "campaign-id",
  "bonusId": "bonus-id",
  "playerId": "player-id",
  "spinsExpirationDuration": 68004,
  "currency": "USD"
}
Property Name Description Type Notes

campaignId

Unique identifier of the free spin campaign on the operator’s side

String

Unique identifier of free spin campaign where the game is available for bonuses (part of the idempotent marker)

bonusId

Unique identifier of the bonus

String

Unique identifier for a player’s bonus within the free spin campaign (part of the idempotent marker)

playerId

Player’s identifier

String

Unique player’s identifier (part of the idempotent marker)

spinsExpirationDuration

Time in millisecond for free spins

Long

Time in milliseconds during which the player can use the free spins from the campaign.
This duration begins immediately after this call is successfully processed.
Free spins expire once this duration elapses. The expiration date might exceed the campaign end date; in this case, players should be allowed to complete their free spin executions until the spinsExpirationDuration period ends.

currency

Free spin’s currency

String

The currency available to the player in the free spin campaign

Response example:
{
  "playerId": "player-id",
  "bonusId": "bonus-id",
  "externalBonusId": "bonus-id-on-providers-side"
}
Property Name Description Type Notes

playerId

Player’s identifier

String

This should be the same id as the one provided in the request

bonusId

Unique identifier of the bonus

String

This should be the same id as the one provided in the request, serving as confirmation that the bonus has been successfully created

externalBonusId

Unique identifier of the bonus

String

Actual identifier that was used (or was assigned by provider) to award bonus to player

6.4.4. Cancelling bonus

This endpoint is used to cancel a previously awarded free spin bonus.
The player identifier and bonus details must be specified.

If an attempt is made to cancel not existing bonus, or cancel already cancelled one (idempotent request) - successful response is returned to indicate that player does not have bonus with the id provided

Request example:
POST /v0/management/bonuses/free-spins/cancel HTTP/1.1
Accept: application/json
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Content-Type: application/json
X-Partner-Key: example
X-Provider-Id: provider

{
  "campaignId": "campaign-id",
  "bonusId": "bonus-id",
  "externalBonusId": "bonus-id-on-providers-side",
  "playerId": "player-id",
  "currency": "USD"
}
Property Name Description Type Notes

campaignId

Unique identifier of the free spin campaign on the operator’s side

String

Unique identifier of the created free spin campaign (part of the idempotent marker)

bonusId

Unique identifier of the bonus

String

Unique identifier for a player’s awarded bonus within the free spin campaign (part of the idempotent marker)

externalBonusId

Unique identifier of the bonus

String

Actual identifier that was used (or was assigned by provider) to award bonus to player

playerId

Player’s identifier

String

Unique player’s identifier (part of the idempotent marker)

currency

Free spin’s currency

String

The currency available to the player in the free spin campaign

Response example:
{
  "playerId": "player-id",
  "bonusId": "bonus-id"
}
Property Name Description Type Notes

playerId

Player’s identifier

String

This should be the same id as the one provided in the request

bonusId

Unique identifier of the bonus

String

This should be the same id as the one provided in the request, serving as confirmation that the bonus has been successfully cancelled

6.4.5. Error handling

If any error occurs during request processing - a JSON response describing the nature of the error is sent.
This response includes:

Property Name Type Description

code

String

Error code identifier.
A list of expected codes is provided below

message

Text

A human-readable error message explaining the error

Below is a list of error codes that can be present in the response:

Code Message Description Status code

error.app.invalid-request-data

Additional information about the validation error

Any validation error encountered during the request processing

400

error.system.cancel-not-supported

Additional information about the system error

Error indicating that cancelling is not supported for provider

422

error.system.external-system-error

Additional information about the system error

Any error encountered during the request processing on provider’s side

422

error.system.unexpected-error

Additional information about the system error

An unexpected error within the system

500

Response example:
{
  "code": "error.app.invalid-request-data",
  "message": "gameId: must not be blank"
}

7. FAQ

Why do some methods not provide sessionToken ?

These methods are considered as "offline", because they can be called outside the active game session.
Eg: round reconciliation, delayed payouts

The wallet must be able to process all these transactions if player exists in the 2-nd level cache (at least 7 days after the game session)

What is the purpose of tournamentWin and promoWin ?

As you may guess, these methods distribute rewards in different tournaments and promo activities.
They are not tied to the concrete game and may be paid with a huge delay after the player’s game session.
This may include: Tournaments, Jackpots, Free Spins, and Free Money on Live casino.

Some features can not be disabled and are supplied as a part of the regular provider’s portfolio, so these methods are mandatory to implement
What is the purpose of bonus and locked balances?

Without regard your wallet supports separate balances or not, the sum of main + bonus + locked is displayed inside the game.

Despite that fact, these details are shared with the providers and are used for the statistics.
In this case some providers offer a discount for the bets paid by the bonus money

Why does gameId in wallet requests and Free Spins API differ from that passed in launch URL ?

During the game launch process is used the unique title identifier.
This allows us to provide you a human-readable, URL-safe identifier without dependency on the provider’s internal logic to be used in your public lobby.

  1. Some providers have an internal games lobby, where player can open any title even if it is not configured

  2. Some providers have different IDs for the game launch and wallet transactions

  3. Some providers have callused IDs, where the gameId is equal between different providers

In case of reverse mapping is required the key is:
providerId + walletGameId = lobbyGameId

How should we implement the idempotency ?

Idempotency is crucial for the proper system functioning.
It helps to avoid any inconsistency during the regular gameplay and in case of system malfunction.
The basic idempotency key includes: playerId , provider, gameId, roundId, txId.
It is essential for you to check whether other fields are valid and equal to the ones in the existing transaction.

The wallet must reply with the tx.processed: true otherwise amount may be added to the invoice twice.

8. Changelog

Version Date Change

v1.0.0

10.04.2023

Added documentation for the operator

v1.0.1

24.04.2023

Updated error handling description

v1.0.2

05.04.2024

Added game launch section

v1.0.3

09.04.2024

Added Data API section

v1.0.4

16.04.2024

Added Authentication section

v1.0.5

18.04.2024

Added Free spins section

v1.0.6

21.04.2024

Added Game Images Management section

v1.0.7

22.07.2024

Added 'sideSplit' transactions field

v1.0.8

23.07.2024

Added 'productType' field to the Data API section

v1.0.9

30.08.2024

Added 'Player Session Token by player details' to the Wallet API section

v1.1.0

19.11.2024

Added NFR & FAQ sections

v1.1.1

27.03.2025

Added Key Concepts & Wallet Responsibility Definition sections