Appearance
Operator wallet contract
OneHazel connects game studios to your wallet. Each studio speaks its own wallet protocol, and OneHazel translates every one of them into one contract that you implement once. You stay the system of record for player balances; OneHazel never holds player funds.
Machine-readable spec: operator-wallet.openapi.yaml (OpenAPI 3.1, no key needed).
The endpoints you implement
OneHazel calls these on your host, under the base path /provider/v1. Every call is an HTTPS POST with a JSON body.
| Endpoint | Purpose |
|---|---|
/session/start | Mint a single-use launch token for a player and game |
/session/exchange | Exchange a launch token for a session token and return the player view |
/session/balance | Return the player's current balance |
/wallet/bet | Debit a stake |
/wallet/win | Credit a win |
/wallet/rollback | Reverse an earlier bet or win |
Authentication
Every call carries Authorization: Bearer <integration key>. You issue the key; OneHazel stores it encrypted against the connection. There is no request-body signature on these calls, so integrity relies on TLS and the key. OneHazel can send the calls from a fixed egress address so you can allowlist it.
Money
Every amount and balance is an integer number of minor units of the player's currency: 1050 is 10.50 in a two-decimal currency. OneHazel converts each studio's own money format to minor units before calling you, so you never see a decimal amount.
Idempotency and replay
Every mutating call carries an idempotency_key:
- Keys are opaque, unique across bets, wins and rollbacks, and stable across a studio's retries of the same transaction.
- A rollback has its own key and names the transaction it reverses in
target_idempotency_key. - When a key has already been processed, do not move money again. Return the original result with
duplicate: true. - That same rule is what makes two simultaneous copies of one transaction safe: the second one sees the first and answers
duplicate: true.
Wallet responses
A wallet call returns the balance after the call and a status:
status | Meaning |
|---|---|
accepted | The bet or win was applied |
insufficient_funds | The stake exceeds the balance; nothing moved (HTTP 402 is also read this way) |
rolled_back | The rollback was applied |
A replay keeps the original status and adds duplicate: true. OneHazel reads a response in this order: duplicate, then insufficient funds, then accepted or rolled_back with an HTTP status below 400. Anything else counts as a failed call.
Errors use { "success": false, "error": { "code": "...", "message": "..." } }. OneHazel branches on error.code, not on the HTTP status alone, because one status can carry different meanings:
| Code | HTTP | When |
|---|---|---|
AUTH_INVALID | 401 | The integration key is wrong |
launch_token_unknown | 401 | The launch token was never issued |
launch_token_expired | 401 | The launch token passed its lifetime |
launch_token_consumed | 409 | The launch token was already exchanged |
session_unknown | 401 | The session token is not recognised |
session_expired | 401 | The session token has expired |
Behaviour worth knowing
- No zero-amount wins. A losing spin's empty win or a round-close acknowledgement is recorded on the OneHazel side and acknowledged to the studio without calling you, so you may reject
amount_minor: 0. - Free-round stakes are not debited. A free-round bet never reaches
/wallet/bet; a win from a free round arrives as a normal/wallet/win. - Rollback carries the original amount. Studios often omit the amount on a cancel, so OneHazel looks it up and forwards it as
metadata.amount_minor. Derive the direction from the target: a reversed bet is a credit, a reversed win is a debit. - Rounds.
round_external_idis the studio's round id; where a studio has no round concept, OneHazel uses the transaction id.round_closed: trueon a win marks the round as finished.
Known limitations today
- Two-decimal currencies only. Zero- and three-decimal currencies are rejected rather than converted.
- No unified launch endpoint. Each studio is launched through its own route today; there is no single OneHazel launch call that covers every studio.
- Demo mode on one studio only. Play without a real wallet session is available for one studio, not across the catalogue.
- Jackpot data is not forwarded. Jackpot contributions and jackpot-win flags that a studio reports are not passed through to your wallet; you receive only the stake and the win amount.
- Free-round issuance on one studio only. Issuing free rounds through OneHazel is supported for one studio. For the others, free-round play is handled as described above, but you cannot issue grants through OneHazel.