Skip to main content

v.1.0.0

Change log

VersionChanges
v1.0.0- Initial Seamless Wallet API release

Introduction

This API provides Seamless wallet integration between Optiplay and your Casino. The API consists of three parts: Games API, Wallet API (including bonuses), and optional Free Rounds API.

Tournaments are handled internally by Optiplay's promo engine and are not exposed as a separate partner-facing API here.

It is important to note that one player can only have one currency (monowallet).

OpenAPI Documentation

OpenAPI documentation is available at: https://integration-api.stage.optiplay.io/api/v1/v13 (stage environment).

The documentation includes endpoints for the Games API, Free Rounds API, and Rounds Report, as well as the ability to generate signatures for POST requests.

Required data for integration

Given by Optiplay

NameDescriptionExample
optiplay_urlOptiplay API URL (stage)https://integration-api.stage.optiplay.io/:casino_id/api
passwordPer-casino signature secrete.g. REPLACE_WITH_YOUR_CASINO_SECRET (illustrative — ask Optiplay integrations for your actual value)

Given by Casino

NameDescriptionExample
casino_urlCasino API URLhttps://yoursite.com/the/api
casino_ip[ ]Casino IP white list127.0.0.1, 192.168.0.1

Communication format

  • Optiplay request URL to Casino starts with [casino_url]
  • Casino request URL to Optiplay starts with [optiplay_url]
  • All requests are GET or POST
  • All message bodies are JSON
  • Messages include Content-Type: application/JSON HTTP header
  • Response bodies contain a status field
  • Messages containing HTTP body such as HTTP POST requests must be signed for authentication.
  • Date format YYYY-MM-DD
  • DateTime format is ISO-8601 extended format (YYYY-MM-DDThh:mm:ss)
  • Time format hh:mm:ss in GMT(UTC) time zone
  • If a request is unsuccessful (status !== 200 || 201) its response will contain an error field with the type of error and a message field with the error description
  • All currencies in messages are based on ISO-4217 format – 3 uppercase letters: USD, EUR, etc.
  • All languages in messages are based on ISO-639-1 format – 2 lowercase letters: en, es, it, etc.
  • All requests are sent using HTTPS protocol.

Money format

Currencies are in ISO-4217 standard format.

Currencies are converted into related precision to maintain integer value. Casino must transform value conforming to the related precision with the currency required.

CurrencyPrecision
EUR2
CLP0
USD2
COP2
JOD3

Mobile and desktop slot games

All games are presented in both mobile and desktop versions. Optiplay requires a query parameter client and launches the corresponding game client (mobile or desktop) depending on it.

About parameter "home"

The parameter "home" has three use cases, depending on its value, the game client reacts differently:

  1. "home" is empty or undefined – the game client hides the button “home”;
  2. "home" = “closePopup” – this case is to handle the game client is opened on a platform’s iframe and the button “home” is pressed;
  3. "home" is something else – this case is to handle the game client is opened on a separate page and user has to return to a platform site

Balance management

Optiplay does not manage the player's balance, but may store the balances received from the Casino

Response status codes

  1. The only acceptable HTTP status codes are 200 or 201

  2. API status codes are contained in the response body

  3. Status codes are similar to the HTTP status codes:

    • The 200 or 201 codes mean a response with successfully processed request;
    • The 4XX codes mean bad request;
    • The 500 code means something bad and unexpected has happened;
CodeDescription
200, 201Successful Response
400Bet limit reached
401Signature invalid
402Insufficient Funds
403Game not allowed,Session expired
404Page not found, Transaction not found
405User is blocked
406Withdraw operation already has a deposit action
409Something went wrong
422Unprocessable Entity (some parameter is invalid)
429Too many requests
430Freerounds not found
500Server error,Unknown Error,Transactions declined

Implementation note: our error resolver currently maps codes starting at 401400 ("Bet limit reached") is not yet mapped to a business error. If your Casino sends 400, verify the response isn't misclassified until this is added.

Authentication

It’s highly recommended to authenticate messages at the prod stage. x-signature header must be included in the HTTP message to sign a message.

x-signature is a hashed sha512 string = HTTP payload + ":" + password (given by Optiplay).

When a message with a signature is received it must be checked that the signature is valid.

If the message has an invalid signature, Casino must return an error message:

{
"status": 401,
"error": "Invalid Signature"
}

The following functions might be used to sign messages:

NodeJS

const crypto = require("crypto");

/**
* @param {string} payload
* @param {string} password
*/
const sign = (payload, password) =>
crypto.createHash("sha512").update(payload + ":" + password).digest("hex");

PHP

function sign(string $payload, string $password): string {
return hash('sha512', $payload . ':' . $password);
}

Games Api

GET /languages

Method: GET

URI: [optiplay_url]/languages

Description: Returns the list of languages available for the Casino

Response Type:

type Result = string[]

Response:

{
"status": 200,
"ts": 1234567890,
"result":[
"bg",
"en",
"cs",
"es",
"go",
"it",
...
]
}

GET /currencies

Method: GET

URI: [optiplay_url]/currencies

Description: Returns the list of currencies available for the Casino

Response Type:

type Result = string[]

Response:

{
"status": 200,
"ts": 1234567890,
"result":[
"EUR",
"LKR",
"MGA",
"UAH",
"USD",
"uBTC",
...
]
}

GET /games

Method: GET

URI: [optiplay_url]/games

Description: Returns the list of games available for the Casino

Response Type:

type Result = {
id: string;
name: string;
logo: string; //Link to game logo image
order: number;
tags?: string[];
};

Response:

{
"status": 200,
"ts": 1234567890,
"result": [
{
"id": 1045,
"name": "Sunny Coin 2",
"logo": "https://.../g1045.jpg",
"order": 2,
"tags": [
"fruits",
"snow"
]
},
{
"id": 2001,
"name": "Royal Hot v2",
"logo": ".https://.../g2001.jpg",
"order": 1
},
...
]
}

GET /freerounds/info

Method: GET

Params:

type Params = {
gameIds?: number[] // List of Optiplay Game IDs (optional)
currencies?: string[] // List of currencies (optional)
}

URI: [optiplay_url]/freerounds/info?gameIds=[ game id ]&currencies=[ currency ]

Descriptions: Returns information about Free Rounds settings available for the Casino

Response Type:

type Result = {
offers: {
currency: string,
game_id: string,
game_name: string,
bets: integer[] //list for free round bets available for the game and currency
}[]
}

Response:

{
"status": 200,
"ts": 1234567890,
"result": {
"offers": [
{
"currency": "UAH",
"game_id": "1045",
"game_name": "Sunny Coin 2",
"bets": [
200,
500,
1000
]
},
{
"currency": "USD",
"game_id": "2001",
"game_name": "Royal Hot v2",
"bets": [
100,
200,
1000
]
},
...
]
}
}

GET /init

Method: GET

Params:

type Params = {
gid: integer // Optiplay Game ID
pid: string // Casino Player ID
currency: string //Casino Player currency
home?: string // Button HOME moves the player to this URL
demo?: integer // Non zero value means the player is the demo
lang?: string // Casino Player language
client?: string // Html Client type. “desktop” or “mobile”
token?: string // Game launch token
countryCode?: string // Casino Player country code (KZ, TR, etc.)
}

URI: [optiplay_url]/init?gid=[ your gid ]&pid=[ your pid ]&currency=[ your currency ]&home=/&demo=0&lang=en&client=desktop&token=[ your token ]

Description: Returns the URL of the chosen game.

The Casino must forward the Player into an iframe with the returned URL. Make sure the iframe has an "allowfullscreen" attribute.

Response Type:

type Result = string

Response:

{
"status": 200,
"ts": 1234567890,
"result": "https://cdn-v2.optiplay.com/3x3-hold-the-spin/v1.9.2?host=sapp.optiplay.com&port=443&lang=en&sid=avkdboqlz"
}

POST /opened

Method: POST

Body:

type Body = {
pid: string; // Casino Player ID
gid: string; // Optiplay Game ID
};

URI: [casino_url]/opened

Description: This request is sent when a player has opened the game.

Response:

{
"status": 200
}

* This request is not being sent by default. If the Casino has a necessity of getting this request, please contact the Optiplay integration team

POST /closed

Method: POST

Body:

type Body = {
pid: string; // Casino Player ID
gid: string; // Optiplay Game ID
};

URI: [casino_url]/closed

Description: This request is sent when a player has closed the game.

Response:

{
"status": 200
}

* This request is not being sent by default. If the Casino has a necessity of getting this request, please contact the Optiplay integration team

Wallet Api

The Casino is expected to implement the Wallet API for Optiplay calls. Each Wallet API response must contain a player’s current balance.

Wallet API POST requests have to be idempotent. Those requests contain a transaction_id field. The Casino has to ensure that requests with the same transaction_id are not processed twice while the duplicate responses have to contain a message "Already processed".

Already processed response example:

{
"status": 200,
"result": {
"balance": 8750,
"currency": "USD",
"message": "Already processed"
}
}

If a withdrawal exceeds the player’s balance, an “Insufficient funds” error response has to be returned. Insufficient funds response example:

{
"status": 402,
"error": "Insufficient funds",
"result": {
"balance": 8750
}
}

Every round has one withdrawal and one deposit request. There are no restrictions on the amount of rounds in the session. FreeRounds are presented as separate rounds.

The type parameter in the deposit and withdraw actions can have the following values:

  • spin – an ordinary round
  • freeRound – a free round provided by Casino
  • prize – a round to send a tournament prize
  • reward – an achievement payout

The type parameter in the cancel action will always have value "refund"

FreeRound type have the withdrawal amount equal to 0.

In case Casino cannot accept withdrawal amount 0, Optiplay can provide configuration that sends withdraw request for these rounds with

{
"amount": "min_bet"
}

where min_bet is the minimum bet amount configured for the current Casino, game and currency, and deposit request with

{
"amount": "min_bet + win_amount"
}

to compensate the withdrawal amount. However, it should be considered that in case player's balance is less than min_bet, player will get Insufficient funds error, though the round is technically free

Error processing

When a game session is interrupted during a game round (for example, a connection failure between the Optiplay client and the Optiplay server) the player can start the game from the lobby once again and continue the game from the same point.

Also a game session may be interrupted due to a transaction error between Optiplay and Casino.

The Optiplay server tries to resend the request automatically if Casino does not respond or the response HTTP status is not 200 or 201.

If all requests fail or some request has incorrect content, the game session will be blocked and the player will see an error message.

{
"status": 403,
"error": "User has unresolved transactions on this game"
}
CodeDescriptionRefundable
400Bet limit reachedfalse
401Invalid Signaturefalse
402Insufficient Fundsfalse
403Game not allowed, Session expiredfalse
404Page not found, Transaction not foundfalse
405User is blockedfalse
406Withdraw operation already has a deposit actionfalse
409Something went wrongtrue
422Unprocessable Entity (some parameter is invalid)true
429Too many requestsfalse
430Freerounds not foundfalse
500Server error, Transaction declinedtrue
  • In case an error with refundable=true occurs on withdraw(bet) transaction a cancel(rollback) transaction will be sent.
  • In case an error with refundable=true occurs on deposit(win) transaction the win transaction will be retried.

GET /balance

Method: GET

Params:

type Params = {
pid: string; // Casino Player ID
token: string; // Game launch token (only if token was provided in init request)
}

URI: [casino_url]/balance

Description: Called when players balance is needed. Casino has to return the player's current balance.

Response Type:

type Result = {
balance: integer; // Casino Player balance
currency: string; // Casino Player currency
}

Response:

{
"status": 200,
"result": {
"balance":8750,
"currency":"USD"
}
}

POST /withdraw

Method: POST

Body:

type Body = {
type: string; // Round type (spin, prize, freeRound)
amount: integer; // Withdrawal amount
tid: string; // Optiplay Transaction ID
pid: string; // Casino Player ID
rid: string; // Optiplay Round ID
gid: string; // Optiplay Game ID
ts: integer; // Transaction timestamp (Unix time in milliseconds)
fr_id?: string; // Free Rounds campaign ID (only if round type=freeRound)
fr_finished?: boolean; //If freeround is last (only if round type=freeRound)
token?: string; // Game launch token (only if token was provided in init request)
}

URI: [casino_url]/withdraw

Description: Withdraws money from the player’s wallet. The Casino has to return the player’s current balance.

Response Type :

type Result = {
balance: integer; // Casino Player balance
transaction_id: string; // Casino Transaction ID
}

Response:

{
"status": 200,
"result": {
"balance": 8750,
"transaction_id": "t-1"
}
}

POST /deposit

Method: POST

Body:

type Body = {
type: string; // Round type (spin, prize, freeRound)
amount: integer; // Deposit amount
tid: string; // Optiplay Transaction ID
pid: string; // Casino Player ID
rid: string; // Optiplay Round ID
gid: string; // Optiplay Game ID
ts: integer; // Transaction timestamp (Unix time in milliseconds)
fr_id?: string; // Free Rounds campaign ID (only if round type=freeRound)
fr_finished?: boolean; //If freeround is last (only if round type=freeRound)
token?: string; // Game launch token (only if token was provided in init request)
}

URI: [casino_url]/deposit

Description: Deposits money to the player’s wallet. The Casino has to return the player’s current balance.

Response Type :

type Result = {
balance: integer; // Casino Player balance
transaction_id: string; // Casino Transaction ID
}

Response:

{
"status": 200,
"result": {
"balance": 8750,
"transaction_id": "t-1"
}
}

POST /cancel

Method: POST

Body:

type Body = {
type: string; // Round type (refund)
tid: string; // Optiplay Rollback Transaction ID
originalTid: string; // Optiplay Bet Transaction ID
pid: string; // Casino Player ID
rid: string; // Optiplay Round ID
gid: string; // Optiplay Game ID
ts: integer; // Transaction timestamp (Unix time in milliseconds)
bet: integer; // Bet amount (just for info)
win: integer; // Win amount (just for info)
token: string; // Game launch token (only if token was provided in init request)
}

URI: [casino_url]/cancel

Description: Rollbacks a bet transaction on Casino and closes the round in order to reverse the transaction and adjust the player’s balance. Casino has to return the money back when receives a Cancel request. Refunds must be made before the response to the request is sent.

Response Type :

type Result = {
balance: integer; // Casino Player balance
transaction_id: string; // Casino Rollback Transaction ID
}

Response:

{
"status": 200,
"result": {
"balance": 8750,
"transaction_id": "t-1"
}
}

Free Rounds Api

Free Rounds (FR) API is an optional API.

The Casino using the FR API is able to grant free bets to users. First-time-user bonuses are supported: FR feature functions even if a player has not played Optiplay games yet.

FR settings may have constraints set by Optiplay: games, currencies, bet values or time.

The Casino may have several FR settings with its constraints. To provide FR to some players, Casino has to specify which FR settings they are based on.

When players use FR their deposit/withdraw bet types are “freeRound”.

POST /freerounds/v2/create

Method: POST

Body:

type Body = {
fr_id: string; // Optiplay FR ID
started_at: datetime; // FR allowed from this time (optional)
finished_at: datetime; // FR allowed to this time (optional)
gid: string | integer []; // List of Optiplay Game IDs
bet_amount: integer; // Bet Amount
rounds: integer; // Amount of FR
pid: string; // Casino Player ID
currency?: string; // Casino Player currency (optional)
}

* As "bet_amount" you can set a value from the list of game bets for currency

URI: [optiplay_url]/freerounds/v2/create

Description: Creates or updates the freerounds settings if exists

Response Type:

type Result = {
fr_id: string // Optiplay FR ID
}

Response:

{
"status":200,
"ts":"1234567890",
"result": {
"fr_id":"13ec1944-4106-42ae-b410-c634a6a08f19"
}
}

POST /freerounds/create

⚠️ WARNING: This method is deprecated

Method: POST

Body:

type Body = {
fr_id: string; // Optiplay FR ID
started_at: datetime; // FR allowed from this time (optional)
finished_at: datetime; // FR allowed to this time (optional)
gid: string | integer []; // List of Optiplay Game IDs
bet_level: integer; // Bet Level
bet_coins: integer; //Bet Coins
rounds: integer; // Amount of FR
pid: string; // Casino Player ID
}

* The total bet is calculated as bet_lines * bet_level * bet_coins, where "bet_lines" is the maximum number of lines in the game.
If the “bet_level” parameter is not set, the default is 1.
If the “bet_coins” parameter is not set, the default is the FR bet is game min bet.

URI: [optiplay_url]/freerounds/create

Description: Creates or updates the freerounds settings if exists

Response Type:

type Result = {
fr_id: string // Optiplay FR ID
}

Response:

{
"status":200,
"result": {
"fr_id":"13ec1944-4106-42ae-b410-c634a6a08f19"
}
}

POST /freerounds/cancel

Method: POST

Body:

type Body = {
fr_id: string // Optiplay FR ID
}

URI: [optiplay_url]/freerounds/cancel

Description: Deletes the freerounds settings if exists.

Jackpots Api

Optiplay extension. This section is not part of the original Seamless Wallet protocol — it's an Optiplay-specific addition for games with a shared jackpot pool. Casinos that don't run jackpot-enabled games can ignore it.

GET /jackpots/balance

Method: GET

Params:

type Params = {
currency: string; // Currency code to convert the jackpot balance into (ISO-4217, 3 letters)
}

URI: [optiplay_url]/jackpots/balance?currency=[ currency ]

Description: Returns the current balance of every active jackpot tier for the Casino, converted into the requested currency.

Response Type:

type Result = {
status: number;
ts: number;
result: {
id: number;
name: string; // Jackpot tier name, e.g. "Minor", "Major", "Mega"
amount: number;
currency: string;
}[];
}

Response:

{
"status": 200,
"ts": 1234567890,
"result": [
{
"id": 23,
"name": "Major",
"amount": 35678,
"currency": "EUR"
},
{
"id": 23,
"name": "Mega",
"amount": 29600,
"currency": "EUR"
}
]
}

GET /jackpots/winners

Method: GET

Params:

type Params = {
limit: number; // Number of winners to return
currency: string; // Currency code to convert winnings into (ISO-4217, 3 letters)
}

URI: [optiplay_url]/jackpots/winners?limit=[ limit ]&currency=[ currency ]

* The Casino is identified by [optiplay_url], not by a request parameter.

Description: Returns the most recent jackpot winners for the Casino.

Response Type:

type Result = {
status: number;
ts: number;
result: {
pid: string; // Casino Player ID
name: string; // Jackpot tier name
date: string; // ISO-8601 datetime
amount: number;
currency: string;
}[];
}

Response:

{
"status": 200,
"ts": 1234567890,
"result": [
{
"pid": "test-1",
"date": "2024-04-04T11:02:13.000Z",
"name": "Major",
"amount": 35678,
"currency": "EUR"
}
]
}

Rounds Report

POST /round/info

Method: POST

Body:

type Body = {
externalId: string // Optiplay round ID
}

URI: [optiplay_url]/round/info

Description: Returns information about specific round.

Note: unlike every other endpoint in this document, the response here is not wrapped in the {status, ts, result} envelope — it uses {info, success} instead. This is intentional and matches our implementation; don't expect the standard envelope for this endpoint.

Response Type:

type Info = {
bet: integer; // Round bet amount
win: integer; // Round win amount
created_at: datetime; // Round created date
closed_at: datetime; // Round closed date
type: string, // Round type (spin, freeRound, prize)
currency: string // Round currency
}

Response:

{
"info": {
"bet": 10,
"win": 100,
"created_at": "2024-01-15T14:27:41.202000Z",
"closed_at": "2024-01-15T14:27:41.278499Z",
"type": "spin",
"currency": "EUR"
},
"success": true
}