Copystake Integration

CopyStake overview

CopyStake consists of two parts:

  • Lobby. The page of active streamers (with video stream) and regular users actively playing allowed games;

  • Broadcast. The page of the selected streamer, where the live stream is displayed (or if it's a regular user, an animation will be shown), where the user can watch the stream, monitor the streamer's bets, and start a copy round;

CopyStake admin configuration:

  • Operator settings. To integrate CopyStake, the Operator needs to implement the API contract (provided below) and specify the following information on the Admin CopyStake page:

    • X-API-KEY - CopyStake will make requests to the Operator with this value in the requestโ€™s header;

    • session TTL - needs to synchronize the session duration between the Operator and CopyStake;

    • callback URL - for sending requests from CopyStake

  • CopyStake settings. A section necessary for configuring games to be added to the whitelist, creating streamers, scheduling video streams, and more.

API Access:

  • all requests from Copystake to Operator contain X-API-KEY with value issued by Operator;

  • all requests from Operator to Copystake contain X-API-KEY with value issued by Copystake;

Signature:

  • all requests from Copystake must be signed by Copystake and verified by Operator;

  • all requests from Operator must be signed by Operator and verified by CopyStake;

  • secretKey for signing the payload in both cases is issued by CopyStake

  • the signature will be placed in the X-REQUEST-SIGNATURE header of each request and uses Base64(HmacSHA512(SecretKey, MD5(request body)))

  • dealing with X-REQUEST-SIGNATURE

Example of how to generate a signature for SecretKey = secret

node Welcome to Node.js v16.13.0. Type ".help" for more information. var crypto = require('crypto'); undefined var hasher = crypto.createHash('md5'); undefined var hashed = hasher.update('{"id":"103193","action":"CREDIT","amount":4.123,"currency":"USD","exchangeRate":0.00203250655485,"tokenAmount":2500,"operatorId":123,"operatorUserId":"333"}') undefined var hash = hashed.digest('hex'); undefined var hmac = crypto.createHmac('sha512', 'secret'); undefined hmac.update(hash); Hmac { _options: undefined, [Symbol(kHandle)]: Hmac {}, [Symbol(kState)]: { [Symbol(kFinalized)]: false } } var sign = hmac.digest('base64'); undefined console.log('signature: ' + sign); signature: IifPVbfXptagZ6qSXH9vYrQiqSP4sKIC+hV+39z2K+FlLzRoEboPGTTymjmeuAhN1i0ICDyyrrufYspgAJmxHQ==

Callback URL:

  • callback_url - provided by Operator, e.g. callback_url=https://integration.operator.com/api/v1/copystake

Original and Copied transactions

Get CopyStake page

This API method allows operators to obtain a link to the CopyStake page, which can be embedded as an iframe into the operator's website.

POST

https://integration.trueplay.io/api/v1/copystake/init

Headers

Content-Type: application/json
X-API-KEY: value issued by CopyStake
X-REQUEST-SIGNATURE: value generated based on the request payload (secret key issued by CopyStake)

Request

Field

Type

Require

Description

userId

String

mandatory

User identifier in the operator system

sessionId

String

optional

Unique session identifier in the operator system. If not provided, it will be generated by CopyStake

currency

String

mandatory

User's active currency (ISO 4217)

balance

Double

mandatory

User's current balance in the operator system, rounded to 8 decimal places

language

String

optional

User's UI language code from the permitted set in the backoffice (ISO 639)

streamId

String

optional

User identifier for active stream. If present, followers are directed to the Broadcast page, skipping the Lobby

Response success

Field

Type

Require

Description

url

String

mandatory

CopyStake URL with an authentication token

sessionId

String

mandatory

Unique session identifier in the operator system. If not provided, it will be generated by CopyStake

Response error

HTTP 400 Bad Request

Field

Type

Require

Description

errorCode

String

mandatory

ERR_UNKNOWN General error status, for cases without a special error code.

ERR_COPYSTAKE_OFF CopyStake is disabled

errorMessage

String

optional

more detailed description of the error

Request example
Request
curl --location 'https://integration.trueplay.io/api/v1/copystake/init' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: d922bd1c-e7ac-4c98-9b1a-baa724440b0e' \
--header 'X-REQUEST-SIGNATURE: XhNkfy6WCTdiewUu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x+77DvqCGRw==' \
--data '{
    "userId": "1",
    "sessionId": "10XFTW12",
    "currency": "USDT",
    "balance": 820.00000000,
    "language": "en",
    "streamId": "7b699688-f4ad-407d-baf5-c006ba8d50e2"
}'

Response example

200 OK
{
    "url": "https://copystake.trueplay.io?token=eyJhbGciOiJIUzUxMiJ9.eyJpZF9vcGVyYXRvciI6โ€,
    "sessionId": "10XFTW12"
}

Get CopyStake page DEMO

This API method allows operators to obtain a link to the CopyStake page, which can be opened in demo mode within an iframe on the operatorโ€™s website.

POST

https://integration.trueplay.io/api/v1/copystake/init-demo

Headers

Content-Type: application/json
X-API-KEY: value issued by CopyStake

Request

Field

Type

Require

Description

language

String

optional

User's UI language code from the permitted set in the backoffice (ISO 639)

streamId

String

optional

User identifier for active stream. If present, followers are directed to the Broadcast page, skipping the Lobby

Response success

Field

Type

Require

Description

url

String

mandatory

CopyStake url with auth token

Response error HTTP

400 Bad Request

Field

Type

Require

Description

errorCode

String

mandatory

ERR_UNKNOWN General error status, for cases without a special error code.

ERR_COPYSTAKE_OFF CopyStake is disabled

errorMessage

String

optional

more detailed description of the error

Request example
Request
curl --location 'https://integration.trueplay.io/api/v1/copystake/init-demo' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: d922bd1c-e7ac-4c98-9b1a-baa724440b0e' \
--header 'X-REQUEST-SIGNATURE: XhNkfy6WCTdiewUu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x+77DvqCGRw==' \
--data '{
    "language": "en",
    "streamId": "7b699688-f4ad-407d-baf5-c006ba8d50e2"
}'

Response example

200 OK
{
    "url": "https://copystake.trueplay.io?token=eyJhbGciOiJIUzUxMiJ9.eyJpZF9vcGVyYXRvciI6โ€
}

Send game transaction

This method allows operators to send transaction data to Trueplay. Operators must provide the relevant details of each transaction.

POST

https://{operator-name}.proxy.trueplay.io/api/v1/accept

Headers

Content-Type: application/json
X-API-KEY: value issued by CopyStake

Field

Type

Require

Description

userId

String

mandatory

User identifier in the operator system

transactionId

String

mandatory

A unique identifier for each transaction type (BET, WIN, ROLLBACK, BONUS_BET, BONUS_WIN). For every new action (BET, WIN, ROLLBACK, BONUS_BET, BONUS_WIN) a distinct transactionId is generated to track that specific action.

referenceTransactionId

String

optional

Used to link related transactions.

โ€ข For BET and BONUS_BET transactions, this will be null as they are the starting point of the sequence.

โ€ข For WIN and BONUS_WIN transactions, this field should reference the transactionId of the corresponding BET or BONUS_BET.

โ€ข For ROLLBACK transactions, this field should reference the transactionId of the original BET or BONUS_BET being rolled back. This also applies to rolling back WIN or BONUS_WIN transactions; the referenceTransactionId should point to the transactionId of the WIN or BONUS_WIN being rolled back.

type

String

mandatory

Type of game transaction (BET | WIN | ROLLBACK | BONUS_BET | BONUS_WIN)

gameProvider

String

mandatory

Indicates the provider of the game or platform associated with the transaction

gamePublisher

String

mandatory

Specifies the gameโ€™s publisher

gameCode

String

mandatory

Unique game code

gameName

String

mandatory

An identifier for the specific game associated with the transaction

gameType

String

mandatory

The type of game

currency

String

mandatory

User's active currency (ISO 4217)

amount

Double

mandatory

Amount involved in the transaction, rounded to 8 decimal places.

Request example
Request
curl --location 'https://integration.trueplay.io/api/v1/copystake/init' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: d922bd1c-e7ac-4c98-9b1a-baa724440b0e' \
--header 'X-REQUEST-SIGNATURE: XhNkfy6WCTdiewUu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x+77DvqCGRw==' \
--data '{
    "userId": "1",
    "transactionId": "111",
    "type": "WIN",
    "gameProvider": "NOLIMIT_CITY"
    "gameProvider": "EVOLUTION",
    "gameCode": "Mental",
    "gameName": "Mental",
    "gameType": "Slots",
    "currency": "USDT",
    "amount": 25.00000000,
}
200 OK

Get user balance

This method retrieves the current available balance of a user during the opening of the Broadcast page and before starting the copy round.

POST

{callback_url}/user-balance

Headers

Content-Type: application/json
X-API-KEY: value issued by Operator
X-REQUEST-SIGNATURE: value generated based on the request payload (secret key issued by CopyStake)

Request

Field

Type

Require

Description

sessionId

String

mandatory

unique session identifier

Response

Field

Type

Require

Description

balance

Double

mandatory

  • rounding to 8 decimal places

  • current available user's balance

currency

String

mandatory

user's active currency ISO 4217

Request example
curl --location '{callback_url}/user-balance' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: e58d1990-31b9-41f5-aa39-fd150643a8fe' \
--header 'X-REQUEST-SIGNATURE: FbS2341Uu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x234FD==' \
--data '{
    "sessionId": "10XFTW12"
200 OK
{
    "balance": 830.00000000,
    "currency": "USDT",
}

Send copied transactions (BET/WIN/ROLLBACK)

Send BET copied transaction

This API method sends a BET copied transaction to the operator immediately after receiving the transaction from the streamer during an active game round.

POST

{callback_url}/bet

Headers

Content-Type: application/json
X-API-KEY: value issued by Operator
X-REQUEST-SIGNATURE: value generated based on the request payload (secret key issued by CopyStake)

Request

Field

Type

Require

Description

sessionId

String

mandatory

Unique session identifier

roundId

String

mandatory

Unique round identifier representing one copy cycle (some number of game actions)

transactionId

String

mandatory

Unique CopyStake transaction identifier

transactionIdOriginal

String

mandatory

Original transaction identifier (the streamer's transaction)

currency

String

mandatory

User's active currency (ISO 4217)

amount

Double

mandatory

Amount, rounded to 8 decimal places, representing the "copied" action's amount to interact with the user's balance on the operator side

Response

Field

Type

Require

Description

balance

Double

mandatory

Current available user's balance, rounded to 8 decimal places

currency

String

mandatory

User's active currency (ISO 4217)

Response error HTTP 400 Bad Request

Field

Type

Require

Description

errorCode

String

mandatory

ERR_UNKNOWN General error status, for cases without a special error code.

errorMessage

String

optional

More detailed description of the error

Request example
curl --location'https://{operator_base_url}/integration/copystake/bet'\
--header 'Content-Type: application/json' \
--header 'X-API-KEY: e58d1990-31b9-41f5-aa39-fd150643a8fe' \
--header 'X-REQUEST-SIGNATURE: FbS2341Uu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x234FD==' \
--data '{
    "sessionId": "10XFTW12",
    "roundId": "1",
    "transactionId": "1",
    "transactionIdOriginal": "111",
    "currency": "USDT",
    "amount": 25.00000000
}'

Response example

200 OK
{
    "balance": 795.00000000,
    "currency": "USDT",
}

Send WIN copied transaction

This API method sends a WIN copied transaction to the operator immediately after receiving the transaction from the streamer during an active game round.

POST

{callback_url}/win

Headers

Content-Type: application/json
X-API-KEY: value issued by Operator
X-REQUEST-SIGNATURE: value generated based on the request payload (secret key issued by CopyStake)

Request

Field

Type

Require

Description

sessionId

String

mandatory

Unique session identifier

roundId

String

mandatory

Unique round identifier representing one copy cycle (some number of game actions)

transactionId

String

mandatory

Unique CopyStake transaction identifier

transactionIdOriginal

String

mandatory

Original transaction identifier (the streamer's transaction)

currency

String

mandatory

User's active currency (ISO 4217)

amount

Double

mandatory

Amount, rounded to 8 decimal places, representing the "copied" action's amount to interact with the user's balance on the operator side

Response

Field

Type

Require

Description

balance

Double

mandatory

Current available user's balance, rounded to 8 decimal places

currency

String

mandatory

User's active currency (ISO 4217)

Request example
curl --location https://{operator_base_url}/integration/copystake/win \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: e58d1990-31b9-41f5-aa39-fd150643a8fe' \
--header 'X-REQUEST-SIGNATURE: FbS2341Uu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x234FD==' \
--data '{
    "sessionId": "10XFTW12",
    "roundId": "1",
    "transactionId": "1",
    "transactionIdOriginal": "111",
    "currency": "USDT",
    "amount": 25.00000000

Response example

200 OK
{
    "balance": 805.00000000,
    "currency": "USDT",
}

Send ROLLBACK BET copied transaction

This API method sends a ROLLBACK BET copied transaction to the operator immediately after receiving the transaction from the streamer during an active game round.

POST

{callback_url}/rollback-bet

Headers

Content-Type: application/json
X-API-KEY: value issued by Operator
X-REQUEST-SIGNATURE: value generated based on the request payload (secret key issued by CopyStake)

Request

Field

Type

Require

Description

sessionId

String

mandatory

Unique session identifier

roundId

String

mandatory

Unique round identifier representing one copy cycle (some number of game actions)

transactionId

String

mandatory

Unique CopyStake transaction identifier

referenceTransactionId

String

mandatory

Reference to BET CopyStake transaction identifier

transactionIdOriginal

String

mandatory

Original transaction identifier (the streamer's transaction)

referenceTransactionIdOriginal

String

mandatory

Reference to original BET transaction identifier

currency

String

mandatory

User's active currency (ISO 4217)

amount

Double

mandatory

Amount, rounded to 8 decimal places, representing the "copied" action's amount to interact with the user's balance on the operator side

Response

Field

Type

Require

Description

balance

Double

mandatory

Current available user's balance, rounded to 8 decimal places

currency

String

mandatory

User's active currency (ISO 4217)

Request example
curl --location 'https://{operator_base_url}/integration/copystake/rollback-bet' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: e58d1990-31b9-41f5-aa39-fd150643a8fe' \
--header 'X-REQUEST-SIGNATURE: FAE3S2341Uu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x23d23d==' \
--data '{
    "sessionId": "10XFTW12",                   
    "roundId": "1",                            
    "transactionId": "3",                      
    "referenceTransactionId": "1",              
    "transactionIdOriginal": "333",             
    "referenceTransactionIdOriginal": "111",
    "currency": "USDT",                        
    "amount": 25.00000000                        
}'

Response example

200 OK
{
    "balance": 830.00000000,
    "currency": "USDT"
}

Send ROLLBACK WIN copied transaction

This API method sends a ROLLBACK WIN copied transaction to the operator immediately after receiving the transaction from the streamer during an active game round.

POST

{callback_url}/rollback-win

Headers

Content-Type: application/json
X-API-KEY: value issued by Operator
X-REQUEST-SIGNATURE: value generated based on the request payload (secret key issued by CopyStake)

Request

Field

Type

Require

Description

sessionId

String

mandatory

Unique session identifier

roundId

String

mandatory

Unique round identifier representing one copy cycle (some number of game actions)

transactionId

String

mandatory

Unique CopyStake transaction identifier

referenceTransactionId

String

mandatory

Reference to BET CopyStake transaction identifier

transactionIdOriginal

String

mandatory

Original transaction identifier (the streamer's transaction)

referenceTransactionIdOriginal

String

mandatory

Reference to original BET transaction identifier

currency

String

mandatory

User's active currency (ISO 4217)

amount

Double

mandatory

Amount, rounded to 8 decimal places, representing the "copied" action's amount to interact with the user's balance on the operator side

Response

Field

Type

Require

Description

balance

Double

mandatory

Current available user's balance, rounded to 8 decimal places

currency

String

mandatory

User's active currency (ISO 4217)

Request example
curl --location 'https://{operator_base_url}/integration/copystake/rollback-win' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: e58d1990-31b9-41f5-aa39-fd150643a8fe' \
--header 'X-REQUEST-SIGNATURE: FAE3S2341Uu0mSUAGw4LwF7GVBa7GT7drJXCvHkI+ORHJQ07uxVKAi3pA/0vB8/shlzX16x23d23d==' \
--data '{
    "sessionId": "10XFTW12",                   
    "roundId": "1",                            
    "transactionId": "4",                      
    "referenceTransactionId": "2",              
    "transactionIdOriginal": "444",             
    "referenceTransactionIdOriginal": "222",
    "currency": "USDT",                        
    "amount": 10.00000000                        
}'

Response example

200 OK
{
    "balance": 830.00,
    "currency": "USDT"
}

Error handling and retry mechanism

CopyStake is very sensitive to the stability and speed of the operator's response and cannot allow long delays in response or a classic retry mechanism with several attempts. In the case of prolonged latency, CopyStack will interrupt the game round but keep the session active. If an error differs from those below, there will be one retry attempt.

Response

Field

Type

Require

Description

errorCode

String

mandatory

ERR_UNKNOWN General error status, for cases without a special error code.

ERR_INSUFFICIENT_FUNDS Not enough money on the user's balance to process a transaction

ERR_DUPLICATE_TRANSACTION A transaction with the same identifier was sent

ERR_USER_DISABLED User is disabled/locked (cannot interact with user's balance)

ERR_INVALID_SIGNATURE Operator couldn't verify the signature on request from

errorMessage

String

optional

more detailed description of the error

Response example

400 Bad Request
{
    "errorCode": "ERR_INSUFFICIENT_FUNDS",
    "errorMessage": "Insufficient balance"
}

Last updated