Appearance
Use your own lobby
Surfaces can fill a block on your page for you. If you already have a lobby, you may not want that. Headless mode gives you the same provider and game list as plain data, and you draw it yourself.
When to use this
- You already have a lobby with your own tiles, rows and search, and you want a provider's games to appear in it.
- You want to decide where the Play button goes and how the game window opens.
If your page has no lobby, use the Surfaces block instead. It draws everything for you.
Which providers appear, and which of their games, is still set in the app under Surfaces. Nothing here changes that.
Install
Use the same script tag as the block, with one extra attribute. Use your own operator id, shown in the app under Surfaces.
html
<script src="https://app.onehazel.com/embed/v1/oh.js"
data-operator-id="op_xxxxx"
data-oh-mode="headless"></script>Nothing renders. The script adds no styles and fills no data-oh-surface block. Your page asks for the data when it wants it.
Read the games
js
window.OneHazel.ready.then(function () {
return window.OneHazel.lobby.games();
}).then(function (lobby) {
lobby.vendors.forEach(function (vendor) {
// draw vendor.name and vendor.games in your own tiles
});
});games() answers { vendors }. The script fetches the list once and reuses it, so calling games() again does not make a second request.
Each vendor has these fields:
| Field | What it is |
|---|---|
key | The provider's short id. You pass it back when you launch a game. |
name | The provider's display name. |
mode | demo for play money. real for a provider you already play for real money. |
games | The games to show, as listed below. |
logoDomain | Optional. The provider's website, for logo lookups. |
Each game has these fields:
| Field | What it is |
|---|---|
code | The game's id. You pass it back when you launch. |
name | The game's display name. |
category | Optional. One of slots, live, crash, virtuals, table, other. |
thumbnail_url | Optional. An https image address. |
Treat the optional fields as possibly missing.
If the list cannot be read, games() rejects with an object whose code is one of:
| Code | Meaning |
|---|---|
surfaces_disabled | Surfaces is not switched on for your account yet. |
operator_unknown | The operator id is missing or not recognised. Check it for typos. |
unavailable | OneHazel answered with an error. The object also has the HTTP status. |
network | The request did not get through. |
A failed load also fires an oh:error event on document with the same code.
Launch a game
Ask for the game address inside the player's click, then open it yourself.
js
playButton.addEventListener('click', function () {
window.OneHazel.lobby.launchUrl('vendor-key', 'game-code', { language: 'en' })
.then(function (url) {
window.open(url, '_blank', 'noopener');
})
.catch(function (err) {
// show your own message; err.code says what went wrong
});
});launchUrl(key, code, options) uses a vendor key and a game code from the list. language is optional and defaults to English. It resolves to an https address. It never opens a window or changes your page, so the click and the window are yours.
Some browsers block a window opened after a wait. If yours does, open a blank window straight away in the click, then set its address when the promise resolves.
The launch is a play-money demo. No wallet is called and no player data is sent.
If the launch fails, the promise rejects with an object:
| Field | What it is |
|---|---|
code | What went wrong, for example game_unknown, invalid_request, unavailable or network. |
message | A short human-readable line, when OneHazel sent one. |
retryable | true when trying again may work. Only set when OneHazel sent it. |
status | The HTTP status, on an unavailable answer that carried no detail. |
game_unknown means the provider is not switched on for demo, or the game is not in its list. A reload of the list usually fixes it. The script also rejects with bad_game_url if the answer is not an https address.
From your server instead
You can skip the script and call the same two routes from your own back end. Both are public and need no key.
bash
curl -i https://api.onehazel.com/onehazel-api/embed/v1/op_xxxxx/manifestThe manifest is cached for 60 seconds and carries a strong ETag. Send it back in If-None-Match and an unchanged manifest answers 304 with no body. The games are under surfaces.lobby.vendors, with the same fields as above.
bash
curl -X POST https://api.onehazel.com/onehazel-api/embed/v1/op_xxxxx/demo-launch \
-H 'Content-Type: application/json' \
-d '{"key":"vendor-key","game_code":"game-code","language":"en"}'The answer is { "game_url": "https://..." }. A failure answers { "code", "message", "retryable" } with the codes in the table above. Optional client_type can be DESKTOP or MOBILE.
Both routes are rate limited per caller, so cache the manifest on your side rather than calling it for every page view. For staging, copy the base address shown in the staging app's snippet.
Keep it fresh
Call window.OneHazel.refresh() to fetch the list again. It resolves to the new manifest. If the fetch fails, the script keeps the last list it read, fires oh:error, and resolves with that kept list, so your page keeps working. It resolves null only when no list was ever read. After it resolves, call games() to read the list.
The list changes when you switch a provider on or off, or choose its games, in the app. A reload of your page picks that up, and so does refresh().
What this is not
- It does not launch real-money games yet. That arrives with the player bridge.
- It sends no per-player data and needs no player login.
- It does not import games into your own system. You read the list when you need it.