Download OpenAPI specification:Download
B2B integration contract for operators and aggregators
The single REST + webhook contract for integrating with the Provider game catalog.
There are two surfaces:
All money is in integer minor units (e.g. cents). All currencies are ISO-4217. All timestamps are RFC 3339 UTC. All requests/responses are JSON.
Authorization: Bearer <operator JWT> issued at onboarding.X-Provider-Signature: <hex(HMAC_SHA256(rawBody, sharedSecret))> — constant-time verify onlyX-Provider-Operator-ID — operator identifierX-Provider-Request-ID — ULID; identifies the transport, used for replay defenseX-Provider-Request-Timestamp — RFC 3339 UTC OR Unix epoch seconds; wall-clock skew limit ± 60 sX-Provider-Algorithm — hmac-sha256 (currently the only value)
Operators MUST reject requests with skew > 60 s, missing/invalid signature, or with
a previously-seen X-Provider-Request-ID within the 5-minute replay window. If the
same request id arrives with a different body, this is a probable attack — return
HTTP 409 + errorCode: 400 and alert.Wallet callbacks are idempotent on (operatorId, transactionId). A duplicate request
MUST return errorCode: 0 with the post-first-call balance, never re-process. Different
body for the same transactionId MUST return errorCode: 400.
All money fields are integer minor units. Decimal places per ISO-4217 (e.g. USD=2, JPY=0, KWD=3). Cross-currency mixing within a single round is forbidden.
| call | retries | total budget |
|---|---|---|
| bet | 3 attempts at 250 / 750 / 2000 ms | ~3 s |
| win | every 30 s | 48 h |
| rollback | every 30 s | 48 h |
| getBalance | none — caller decides | n/a |
Bets MUST NOT be retried on errorCode = 200 (insufficient funds) or
errorCode = 202 (self-excluded). Wins / rollbacks MUST always eventually settle;
failed rounds are reported via the round-close monitor at /v1/rounds/{id}.
| code | meaning |
|---|---|
| 0 | OK |
| 100 | INVALID_SIGNATURE |
| 101 | INVALID_REQUEST |
| 102 | PLAYER_NOT_FOUND |
| 103 | INVALID_CURRENCY |
| 200 | INSUFFICIENT_FUNDS |
| 201 | PLAYER_LIMIT_EXCEEDED |
| 202 | PLAYER_SELF_EXCLUDED / risk locked |
| 300 | GAME_DISABLED |
| 301 | GAME_MAINTENANCE |
| 400 | DUPLICATE_TRANSACTION_DIFFERENT_PAYLOAD |
| 401 | TRANSACTION_NOT_FOUND |
| 500 | INTERNAL_ERROR |
Returns the games this operator is entitled to, optionally narrowed by jurisdiction/currency. Entitlements are managed per-operator: an operator with a non-empty game allow-list sees ONLY those games; an operator with no allow-list sees the entire catalog.
| jurisdiction | string Example: jurisdiction=CW |
| currency | string Example: currency=USD |
{- "games": [
- {
- "id": "skyrush",
- "name": "SkyRush",
- "engine": "crash",
- "rtp": 0.97,
- "volatility": "low",
- "minBet": {
- "amount": 0,
- "currency": "str"
}, - "maxBet": {
- "amount": 0,
- "currency": "str"
}, - "maxWin": {
- "amount": 0,
- "currency": "str"
}, - "maxMultiplier": 10000,
- "jurisdictions": [
- "CW"
], - "currencies": [
- "USD"
], - "languages": [
- "en"
],
}
]
}{- "id": "skyrush",
- "name": "SkyRush",
- "engine": "crash",
- "rtp": 0.97,
- "volatility": "low",
- "minBet": {
- "amount": 0,
- "currency": "str"
}, - "maxBet": {
- "amount": 0,
- "currency": "str"
}, - "maxWin": {
- "amount": 0,
- "currency": "str"
}, - "maxMultiplier": 10000,
- "jurisdictions": [
- "CW"
], - "currencies": [
- "USD"
], - "languages": [
- "en"
],
}| userId required | string External player ID at the operator |
| gameId required | string |
| currency required | string = 3 characters |
| language required | string |
| mode | string Default: "real" Enum: "real" "demo" |
| kycLevel | integer [ 0 .. 3 ] Default: 1 |
| ipAddress | string |
| deviceFingerprint | string |
| returnUrl | string <uri> |
| depositUrl | string <uri> |
{- "userId": "string",
- "gameId": "string",
- "currency": "str",
- "language": "en",
- "mode": "real",
- "kycLevel": 1,
- "ipAddress": "string",
- "deviceFingerprint": "string",
}{- "sessionId": "string",
- "token": "string",
- "expiresAt": "2019-08-24T14:15:22Z"
}{- "id": "string",
- "gameId": "string",
- "userId": "string",
- "startedAt": "2019-08-24T14:15:22Z",
- "endedAt": "2019-08-24T14:15:22Z",
- "status": "open",
- "bet": {
- "amount": 0,
- "currency": "str"
}, - "win": {
- "amount": 0,
- "currency": "str"
}, - "outcome": { },
- "provablyFair": {
- "serverSeedHash": "string",
- "serverSeed": "string",
- "clientSeeds": [
- "string"
], - "nonce": 0,
- "algorithm": "aviator-sha512"
}
}| userId | string |
| gameId | string |
| status | string Enum: "open" "settled" "expired" "cancelled" |
| from | string <date-time> |
| to | string <date-time> |
| limit | integer <= 1000 Default: 100 |
{- "rounds": [
- {
- "id": "string",
- "gameId": "string",
- "userId": "string",
- "startedAt": "2019-08-24T14:15:22Z",
- "endedAt": "2019-08-24T14:15:22Z",
- "status": "open",
- "bet": {
- "amount": 0,
- "currency": "str"
}, - "win": {
- "amount": 0,
- "currency": "str"
}, - "outcome": { },
- "provablyFair": {
- "serverSeedHash": "string",
- "serverSeed": "string",
- "clientSeeds": [
- "string"
], - "nonce": 0,
- "algorithm": "aviator-sha512"
}
}
]
}| userId | string |
| gameId | string |
| roundId | string |
| method | string Enum: "bet" "win" "rollback" |
| status | string Enum: "pending" "committed" "rolled_back" "failed" |
| from | string <date-time> |
| to | string <date-time> |
| limit | integer <= 1000 Default: 100 |
{- "transactions": [
- {
- "id": "string",
- "operatorTxnId": "string",
- "method": "bet",
- "status": "pending",
- "userId": "string",
- "sessionId": "string",
- "gameId": "string",
- "roundId": "string",
- "amount": 0,
- "currency": "str",
- "referenceTxnId": "string",
- "responseBalance": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "settledAt": "2019-08-24T14:15:22Z"
}
]
}| from required | string <date-time> |
| to required | string <date-time> |
| gameId | string |
| currency | string |
{- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z",
- "rows": [
- {
- "gameId": "string",
- "currency": "string",
- "betsCount": 0,
- "betsAmount": 0,
- "winsAmount": 0,
- "ggr": 0
}
]
}| from required | string <date> |
| to required | string <date> |
| gameId | string |
| currency | string |
{- "rows": [
- {
- "operatorId": "string",
- "day": "2019-08-24",
- "gameId": "string",
- "currency": "string",
- "betsCount": 0,
- "betsAmount": 0,
- "winsCount": 0,
- "winsAmount": 0,
- "rollbacksCount": 0,
- "rollbacksAmount": 0,
- "bonusCost": 0,
- "uniquePlayers": 0,
- "roundsCount": 0,
- "ggr": 0,
- "ngr": 0
}
]
}| userId required | string |
object (Money) | |
object (Money) | |
object (Money) | |
| sessionTimeMinutes | integer >= 1 |
| realityCheckMinutes | integer >= 1 |
{- "dailyLossLimit": {
- "amount": 0,
- "currency": "str"
}, - "weeklyLossLimit": {
- "amount": 0,
- "currency": "str"
}, - "monthlyLossLimit": {
- "amount": 0,
- "currency": "str"
}, - "sessionTimeMinutes": 1,
- "realityCheckMinutes": 1
}| userId required | string |
| duration required | string Enum: "24h" "7d" "30d" "6m" "permanent" |
| reason | string |
{- "duration": "24h",
- "reason": "string"
}Outbound product webhooks (provider → operator). Subscribe per-event in
the back-office; each subscription gets its own HMAC secret. At-least-once
delivery with exponential backoff; dedupe on the envelope id.
Fired once per round when it transitions open → settled. Headers match
the wallet-callback signing scheme (X-Provider-Signature,
X-Provider-Operator-ID, X-Provider-Request-Timestamp,
X-Provider-Algorithm: hmac-sha256) plus X-Provider-Event: round.settled
and X-Provider-Delivery-ID. The signature covers the raw JSON body.
| id required | string Stable per-delivery id ( |
| event required | string Event name (matches the subscription). |
| operatorId required | string |
| occurredAt required | string <date-time> When the underlying event was recorded (not the delivery attempt time). |
required | object Event-specific payload (see the per-event schemas). |
{- "id": "whd_10472",
- "event": "round.settled",
- "operatorId": "op_demo",
- "occurredAt": "2019-08-24T14:15:22Z",
- "data": {
- "operatorId": "string",
- "roundId": "string",
- "gameId": "skyrush",
- "userId": "string",
- "currency": "USD",
- "betAmount": 0,
- "winAmount": 0,
- "outcome": { },
- "at": "2019-08-24T14:15:22Z"
}
}| id required | string Stable per-delivery id ( |
| event required | string Event name (matches the subscription). |
| operatorId required | string |
| occurredAt required | string <date-time> When the underlying event was recorded (not the delivery attempt time). |
required | object Event-specific payload (see the per-event schemas). |
{- "id": "whd_10472",
- "event": "round.settled",
- "operatorId": "op_demo",
- "occurredAt": "2019-08-24T14:15:22Z",
- "data": {
- "txnId": "string",
- "operatorId": "string",
- "operatorTxnId": "string",
- "method": "bet",
- "userId": "string",
- "gameId": "string",
- "roundId": "string",
- "amount": 0,
- "currency": "string",
- "balance": 0,
- "at": "2019-08-24T14:15:22Z"
}
}