Overview & Specs
Official technical specification for integrating with The Ear Platform seamless external wallet service. This documentation details all request/response models, mandatory security signature algorithms, idempotency guarantees, and interactive testing utilities.
Seamless External Wallet
Single source of truth for player funds. Debit bets, credit winnings, and issue refunds directly in real time.
SHA-256 Signature
All financial and balance requests are cryptographically authenticated using URL-encoded parameter hashing with a shared private key.
Strict Idempotency
Network retries with identical transactionId are automatically
reconciled without duplicate debits or credits.
Sequence & Protocol
The integration follows a sequential handshake: game session launch is validated by an immediate
GetUserInfo call,
followed by game rounds consisting of atomic bet debits, win credits, or transaction reversals.
Game Launch (Get play url)
The operator initiates a POST request to the provider URL with gameId,
playerId, brandId, and session token sid. The response yields the
playable iframe URL.
Session Handshake & Balance Check (GetUserInfo / GetBalance)
Before allowing gameplay, The Ear Platform issues a POST <theear_url>/GetBalance
call containing the player's sid and computed SHA-256 signature to retrieve current wallet
balance.
Wager Placement - Bet (/bet)
When a player spins or bets, a POST call debits the player's balance. Each bet features a unique
transactionId (e.g. D_123456) and a roundId.
Payout or Loss Settlement - Win (/win)
When the spin concludes, a POST call credits the balance with winnings using a unique
transactionId (e.g. C_123456). Losses are represented as a win with
amount: 0.
Void / Reversal - Refund (/refund)
In case of round disruption or cancelled games, a refund POST call references the original bet's
transactionToRefund to restore player balance safely.
Session Management (sid)
The sid field is a UUID token that uniquely identifies each active session for each player.
Core Session Directives
- Mandatory in Real Mode: All calls, including
GetUserInfo,/bet,/win, and/refund, must contain the activesid. - No Multi-Sessions: A single player cannot have multiple active sessions simultaneously. Opening a new game session invalidates previous tokens.
- Play-for-Fun Mode: In fun mode (
isFreeGame: 1), thesidtoken is omitted or treated as purely temporary.
Idempotency Model
Network retries must never result in duplicate billing or double credits.
transactionId will be handled with strict idempotency.
No subsequent debit, credit, or refund will be executed; instead, the original transaction's balance snapshot
and details will be returned directly.
Hash Calculation Formula
Calculate the authentication hash using all request body parameters concatenated with the private key shared with The Ear Platform. All parameters must be URL-encoded without spaces before computing the SHA-256 digest.
Formula & Algorithm
SHA256( URLENCODE( COMPACT_JSON_WITHOUT_HASH ) + PRIVATE_KEY )
Step-by-Step Walkthrough:
- Strip Hash Parameter: Remove the
hashproperty itself from the JSON payload. - Compact JSON: Serialize the JSON without any extraneous spaces, newlines, or whitespace.
- URL Encode: URL-encode the serialized string (e.g.
{"amount":0.1}becomes%7B%22amount%22%3A0.1%7D). - Append Secret: Concatenate the shared private key directly to the end of the URL-encoded string.
- Compute SHA-256: Generate standard 64-character lowercase hexadecimal SHA-256 hash.
Live Hash Generator
Paste any payload and private key below to inspect every intermediate transformation of The Ear Platform hash algorithm in real time.
Postman Pre-Request Script
Automate hash generation in Postman using this ready-to-copy Pre-request Script.
Store your shared private key in an environment variable named THE_EAR_PRIVATE_KEY.
// Parse current request body
let body = {};
try {
body = JSON.parse(pm.request.body.raw);
} catch (e) {
console.error("Invalid JSON body", e);
}
// 1. Remove existing hash if present
delete body.hash;
// 2. Compact JSON string without whitespace
let rawJson = JSON.stringify(body);
// 3. URL-encode string
let urlEncoded = encodeURIComponent(rawJson);
// 4. Retrieve private key and concatenate
let privateKey = pm.environment.get("THE_EAR_PRIVATE_KEY") || "theear_secret_demo_key_2026";
let stringToSign = urlEncoded + privateKey;
// 5. Compute SHA-256 hash using CryptoJS
let calculatedHash = CryptoJS.SHA256(stringToSign).toString();
// 6. Inject hash back into request payload
body.hash = calculatedHash;
pm.request.body.raw = JSON.stringify(body, null, 2);
Endpoints Reference
Comprehensive schema, parameter definitions, and usage examples for all five core endpoints.
Initiates a game session by requesting the launch URL from the provider. Returns the playable game iframe URL for either real-money or play-for-fun modes.
| Property | Type | Required | Description & Constraints |
|---|---|---|---|
| gameId | string | Required | Game identifier to start (varchar, numeric, or alphanumeric). |
| playerId | string | Required | Single player identifier. Maps to userId in subsequent GetBalance
requests. |
| brandId | string | Required | Brand format: theearplatform_{OPERATOR} (e.g. theearplatform_4003). |
| sid | string | Real Only | UUID session token. Mandatory in real mode (isFreeGame: 0). Omitted in fun mode. |
| displayName | string | Optional | In-game username. Defaults to {OPERATOR}_{playerId} (e.g. 4003_6). |
| mobile | boolean | Required | true for mobile touch client; false for desktop. |
| language | string | Required | ISO 639-1 language code (e.g. "en", "it"). |
| isFreeGame | integer | Required | 0 for Real Money mode; 1 for Play-For-Fun mode. |
| returnUrl | string | null | Optional | Redirect URL when home button clicked or game closes. Can be null. |
| currency | string | Required | ISO 4217 currency code (e.g. "EUR", "USD"). |
{
"gameId": "gameId",
"playerId": "6",
"brandId": "theearplatform_4003",
"sid": "6370cc15-ee67-4e0f-afaf-a9132c942769",
"displayName": "4003_6",
"mobile": false,
"language": "en",
"isFreeGame": 0,
"returnUrl": null,
"currency": "EUR"
}
Triggered immediately following real game initialization to authenticate the session token and fetch the current player wallet balance.
| Property | Type | Required | Description |
|---|---|---|---|
| userId | string | Required | Single player ID (corresponds to playerId from game launch). |
| gameId | string | Required | Game ID provided by provider. |
| providerName | string | Required | Name of provider stored in platform configuration. |
| sid | string | Required | Active UUID session token. |
| userCurrency | string | Required | Currency used by the player (e.g. "EUR"). |
| hash | string | Required | Calculated SHA-256 signature using URL-encoded parameters + private key. |
{
"balance": 256.20,
"message": "OK"
}
Deducts the wager amount from the player's balance. Idempotent per transactionId.
| Property | Type | Required | Description |
|---|---|---|---|
| amount | number | Required | Wager amount to withdraw from player balance (e.g. 0.10). |
| playerId | string | Required | Player identifier. |
| currency | string | Required | ISO 4217 currency code. |
| gameId | string | Required | Game ID. |
| sid | string | Required | Active session token UUID. |
| roundId | string | Required | Round cycle identifier. Shared across bet, win, refund, and loss. |
| transactionId | string | Required | Unique transaction ID (conventionally prefixed D_, e.g. D_123456). |
| hash | string | Required | Calculated SHA-256 signature. |
{
"balance": 250.36,
"transactionId": "56985541",
"message": "OK"
}
Credits round winnings to player balance. If the round is a loss, send amount: 0.
| Property | Type | Required | Description |
|---|---|---|---|
| amount | number | Required | Winning amount to credit (two decimal places). For round loss, set to 0. |
| playerId | string | Required | Player identifier. |
| roundId | string | Required | Cycle identifier matching original bet. |
| transactionId | string | Required | Unique transaction ID (conventionally prefixed C_, e.g. C_123456). Must
differ from bet's ID. |
| hash | string | Required | Calculated SHA-256 signature. |
{
"balance": 500.36,
"transactionId": "85967123",
"message": "OK"
}
Restores player balance for a previously debited bet in case of cancelled or interrupted rounds.
| Property | Type | Required | Description |
|---|---|---|---|
| amount | number | Required | Amount to refund to player balance. |
| transactionToRefund | string | Required | The original bet's transactionId to validate and refund (e.g. D_123456).
|
| transactionId | string | Required | Unique refund transaction ID (conventionally prefixed R_, e.g.
R_123456).
|
| hash | string | Required | Calculated SHA-256 signature. |
{
"balance": 500.36,
"transactionId": "654654321",
"message": "OK"
}
HTTP Status Rules
In case of an error in any call, an HTTP status code other than 200 will be returned.
Error codes inside the body are not used; the HTTP status code indicates the failure class, and the
message field describes the specific cause.
message must be "OK".
422 Unprocessable Content
Returned when one or more required fields are missing from the request body.
{
"user_currency": [
"The user currency field is required."
]
}
404 Incorrect sid
Returned when an invalid or non-existent session ID (sid) is supplied.
{
"message": "User not found"
}
500 INVALID HASH
Returned when the calculated SHA-256 signature does not match the parameters and shared private key.
{
"message": "INVALID HASH"
}
500 Session Expired
Returned when the player's session token has timed out or expired.
{
"message": "Session expired"
}
500 Transaction Error
Returned when a financial transaction cannot be completed (e.g. database lock, insufficient player balance).
{
"balance": 10051.31,
"transactionId": null,
"message": "Transaction error"
}
500 Wrong Refund Target
Returned on /refund when the referenced original bet transaction ID does not exist in the
database.
{
"balance": 10051.91,
"transactionId": null,
"message": "Transaction with id =D_641738e0-7091-4d3c-b1b0-9dbad5cb8a4c6 doesn’t exists."
}
Testing Console
{
"balance": 256.20,
"message": "OK"
}
content-type: application/json; charset=utf-8 x-theear-server: aggregator-sandbox-v1 x-execution-mode: isolated-sandbox x-request-id: req_init