Loading…

Integration docs

Everything you need to integrate the seamless-wallet API: authentication, the core endpoints, webhook signature verification, error codes and our official SDKs.

Authentication

Every request carries your operator API key as a bearer token. Keys are environment-specific — sandbox keys can only open demo sessions.

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx

Responses are JSON. Non-2xx responses use a stable envelope: { "errorCode": number, "errorDescription": string }. Rate-limit headers (X-RateLimit-*) and a correlation X-Request-Id are returned on every call.

Create a session
POST /v1/sessions
Authorization: Bearer sk_live_…
Content-Type: application/json

{
  "userId": "player-123",
  "gameId": "skyrush",
  "currency": "USD",
  "language": "en",
  "mode": "real"
}

# → 201
{
  "sessionId": "sess_…",
  "launchUrl": "https://launcher.provider.gg/launch/skyrush?token=…",
  "token": "…",
  "expiresAt": "2026-06-03T12:00:00.000Z"
}
Core endpoints
All paths are relative to your environment base URL.
MethodPathDescription
GET/v1/gamesList entitled games
GET/v1/games/:idGame detail & limits
POST/v1/sessionsCreate a launch session
GET/v1/roundsList rounds (filterable)
GET/v1/rounds/:idRound detail + receipt
GET/v1/transactionsList wallet transactions
GET/v1/reports/dailyDaily aggregated report
POST/v1/players/:id/limitsSet RG limits
POST/v1/players/:id/excludeSelf-exclude a player
GET/v1/webhooksList webhook subscriptions
POST/v1/webhooksCreate/rotate a subscription
Verify webhooks — Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';

// Express handler. Use the RAW body, not the parsed JSON.
app.post('/webhooks/provider', (req, res) => {
  const sig = req.header('X-Provider-Signature') ?? '';
  const ts  = req.header('X-Provider-Timestamp') ?? '';
  const raw = req.rawBody; // Buffer/string of the exact payload

  // Reject replays older than 5 minutes.
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);

  const expected = createHmac('sha256', WEBHOOK_SECRET)
    .update(`${ts}.${raw}`)
    .digest('hex');

  const ok = sig.length === expected.length &&
    timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  if (!ok) return res.sendStatus(401);

  // ... handle event ...
  res.sendStatus(200);
});
Verify webhooks — Python
import hmac, hashlib, time

def verify(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool:
    if abs(time.time() - int(timestamp)) > 300:
        return False
    msg = f"{timestamp}.".encode() + raw_body
    expected = hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature, expected)

The same scheme is implemented in our SDKs, so you rarely need to write this by hand.

Error codes
CodeNameMeaning
1000INVALID_REQUESTMalformed or missing parameters
1002INVALID_SIGNATUREBad bearer token or HMAC
2001INSUFFICIENT_FUNDSPlayer wallet cannot cover the bet
2002PLAYER_NOT_FOUNDUnknown player
3001GAME_DISABLEDGame not entitled for operator
4001TRANSACTION_NOT_FOUNDNo such round/transaction
5000INTERNAL_ERRORTransient server error — retry
Official SDKs
Same signing contract across every language.
TypeScript / Node@provider/operator-api-sdk
npm i @provider/operator-api-sdk
Pythonprovider-operator-sdk
pip install provider-operator-sdk
PHPprovider/operator-sdk
composer require provider/operator-sdk
Javacom.provider:operator-sdk
implementation "com.provider:operator-sdk:1.0.0"