Live-camera betting · by Adkuu
Lukk for betting platforms
Lukk is a B2B game and content provider. You keep the player relationship and the funds; Lukk supplies the stream, the markets, the pricing, the settlement and the widget. Money moves through your wallet API per transaction, exactly like any other game provider on your floor. Early access: Adkuu is onboarding its first operators (integration guide v1.1, 6 October 2026).
Two ways to integrate
| A · Widget (iframe) | B · Feed (API / WebSocket / gRPC) | |
|---|---|---|
| You build | almost nothing: mint a launch session, frame the widget | your own UI: video, market cards, bet slip |
| Player watches and bets | inside the Lukk widget, in your colours | inside your UI |
| Markets and prices | handled inside the widget | you consume the feed |
| Wallet | your wallet API, per transaction | your wallet API, per transaction |
| Settlement | signed webhooks and/or pull | signed webhooks and/or pull |
| Best for | fast launch, full parity, least effort | full control of look and flow |
| Effort | an afternoon | days |
Both paths share one identity model, one wallet contract, one risk engine and one settlement backbone. Many operators run both: the widget on mobile, a custom UI on web, against a single operator account.
Credentials and the security model
At onboarding you receive an operator id (public), an operator API key (your backend only — it mints launch sessions and signs Lukk's calls to your wallet), a webhook secret, and optionally a feed key. Your account carries the settings Lukk applies on every market at once: execution_mode (house or amm), margin_add_pts, currency, wallet_mode and wallet_url, webhook_url, embed_origins, embed_config (branding and stake presets) and your limits.
- Launch tokens are single-use and expire after 120 seconds: a copied iframe URL is dead after its first load.
- The widget document is served with a per-operator
frame-ancestorspolicy built from your registeredembed_origins: browsers refuse to render it anywhere else. - Every money mutation is idempotent on your ticket or transaction key: retries and replays return the original decision, never a second one.
- The postMessage bridge is origin-checked in both directions. Keys rotate on request with no downtime.
Player identity stays yours. You pass an opaque player_ref; Lukk never sees a name, an email or a balance. KYC, AML, age verification and responsible-gambling enforcement are your duties; Lukk enforces the per-ticket limits and self-exclusion context you pass and stays PII-free.
Quick start: the widget in an afternoon
- Settings. Your account team sets your mode, margin, currency, limits,
embed_origins(production and staging sites),wallet_url,webhook_urland your default theme. - Mint a launch session from your backend, one call per player visit:
POST /api/v1/b2b/embed/sessionswithx-operator-key, aplayer_ref, and optionally achannel,currencyandtheme. You get alaunch_url, alaunch_tokenandexpires_in_s(120). - Frame it. The
launch_urlis the iframesrc. The widget fills whatever box you give it and chooses a stacked or wide layout from that box; the best experience is a full-viewport stage with only your own thin chrome (a close control and your balance). - The bridge. Listen for
lukk:ready,lukk:bet,lukk:session_expired,lukk:relaunch_requestandlukk:error; sendlukk:relaunch(a fresh token),lukk:themeandlukk:refresh_balance. - Your wallet API. Four endpoints — debit, credit, rollback, reconcile — and players are betting.
POST https://api.lukk.gg/api/v1/b2b/embed/sessions
x-operator-key: <your operator key>
Content-Type: application/json
{ "player_ref": "u-8841", "channel": "crossings", "currency": "EUR",
"theme": { "colors": { "accent": "#1e90ff" } } }
→ { "launch_token": "…",
"launch_url": "https://lukk.gg/embed/your-brand?lt=…&channel=crossings&api=https://api.lukk.gg",
"expires_in_s": 120 }If Lukk is unavailable — the API unreachable, no live channel, a missing or expired token — the widget still loads from a static edge, plays its starting screen and settles into a calm "Lukk isn't available at the moment" message with a Try again control. Your page receives a lukk:error and can offer a way back; there is nothing you need to detect or render yourself.
Wallet: the seamless contract
Lukk never holds player funds. It moves money against your wallet API per transaction — the standard game-provider model:
bet accepted ──► POST {wallet_url}/debit (synchronous: no debit, no bet)
bet won/void ──► POST {wallet_url}/credit (queued, retried until delivered)
placement
failed ──► POST {wallet_url}/rollback (returns a debited stake)
daily ──► POST {wallet_url}/reconcile (two-party cross-check)- A debit is synchronous and fail-closed: Lukk accepts the bet only after your 200. Answer within 5 seconds; slower counts as a transport failure and the bet is refused.
- A credit or rollback is enqueued at settlement and delivered at least once with retries — respond fast, dedupe on
idem_key, never rely on order. A lost bet moves no money and produces no wallet call. - Every call carries
X-Lukk-Signature: sha256=<hex>— an HMAC-SHA256 of the raw request body with your operator API key as the secret. Verify with a constant-time compare on the bytes you received, then parse. - Amounts are decimals with two places in your account currency (EUR, USD, SOL …). The debit
metacarries the ticket, market title, scene, side, entry price, potential payout and placement time, so an open position can appear in your own bet history at once. - Once a day Lukk calls
reconcilefor the previous window (with a two-hour overlap), diffs your log against its ledger key by key and alarms on any divergence. It never auto-adjusts. The same figures are available any time fromGET /api/v1/b2b/wallet/statementandGET /api/v1/b2b/wallet/transactions.
Settlements
Markets settle in seconds after their window closes (median under five seconds; larger payouts carry a short verification hold). You learn the result two ways, same line shape:
- Webhook. Lukk POSTs each settled ticket to your
webhook_url, at least once, with exponential backoff; headersX-Lukk-Event: settlement,X-Lukk-Delivery,X-Lukk-Signature(HMAC of the raw body with your webhook secret).stateiswon,lostorrefunded; the body carries the stake, entry price, payout,rule_hash,execution_modeand the resolution block (winning_outcome,void,source). Dedupe onsettlement.bet_id. - Pull.
GET /api/v1/b2b/settlements?since=<ISO>&limit=200returns the same lines, cursor-paged, with page totals (stakes, payouts, hold) for netting. Use it as the daily safety net even if you take webhooks.
Show players won with the payout, lost with the winning outcome, and refunded as a return — every void is a full refund, never a re-grade in anyone's favour.
Branding the widget
You describe your brand once with a handful of semantic colours (background, surface, surface_raised, border, text, text_muted, accent, accent_text, positive, negative, warning, live); Lukk derives the full palette. Typography (a font family and a stylesheet from Google Fonts or Bunny Fonts), corner radius (0–24 px), and two chrome switches (the small Lukk lock-up on the starting screen, the live activity strip) are yours too. Presets: lukk, dark, light.
Three places to set it, one precedence order: the account default, a per-session override at mint time (dark/light variants, one brand per skin, A/B tests), and a live lukk:theme message that re-brands the running widget in place. Each layer is a deep merge over the previous one. The stake_presets you configure (up to six amounts in your currency) become the quick-stake chips.
The layout, the market cards' anatomy, the countdowns and the evidence flash stay Lukk's — they carry the fairness cues players learn once and keep across operators.
Prices, limits and rejections
In house mode every outcome shows your decimal odds (the Lukk price with your margin, adjusted for the liability already on that outcome), with the fair chance as a small caption, and the payout a ticket would lock. In amm mode the button shows the live probability. A ticket locks the odds at the moment it is accepted — one to three seconds after the tap — and pays stake × those odds.
Minimum stake, maximum stake per bet and maximum payout per bet are set on your account in your currency; the widget's bet drawer and the feed's limits block publish them and the acceptance pipeline enforces them on every ticket. Per-outcome liability caps and circuit breakers protect the book on top.
Rejections you may see through the bridge or the API, all terminal for that ticket: insufficient_funds, min_stake, max_stake, max_payout, price_moved, quote_expired, in_flight_event, suspended, outcome_suspended, circuit_breaker, betting_closed, stale_price, oracle_lag. The player simply places again at the new price.
Building your own UI (the feed path)
- Snapshot
GET /api/v1/b2b/feed(optionalx-operator-keyfor prices personalised to your margin and mode): every open market with both views — fair probabilities and margined fixed odds — timing (open_ts,close_ts,bet_close_ts, price age, oracle lag, acceptance delay), status, limits and the frozenrule_hash; plus the recently settled markets with their resolution block. - Live updates over WebSocket
wss://api.lukk.gg/ws/v1(topicb2b:feed) within a second of any change, with resume after a reconnect, and a gRPC mirror for dedicated integrations. - Quote → ticket.
GET /api/v1/b2b/quote/{slug}?side=YES&stake=5(a price locked for about 3 s) thenPOST /api/v1/betswith a player session token and yourticket_idas the idempotency key. Every ticket passes the same gates: the acceptance delay with an in-flight veto, price protection and the wallet debit. - Clock sync
GET /api/v1/b2b/timeso countdowns run on server time. The server is the authority anyway — a player on a delayed stream can be refused, never filled stale. - Discovery
GET /api/v1/b2b/contract(no auth) lists schema versions, transports and capabilities. Schemas are versioned (lukk.feed.v1,lukk.webhook.v1); additive fields never bump a version.
The complete feed specification — schemas, the WebSocket resume protocol, the gRPC service, quote and ticket semantics, stream synchronisation — is the Lukk Stream Feed operator integration specification; ask the account team for the current version.
Who is responsible for what
| Yours (the licensee) | Lukk's (the supplier) |
|---|---|
| the player, the funds, KYC / AML / age | an opaque player_ref; no PII, no balances |
| deposit and withdrawal rails, currency | one currency per account; exact decimals |
| responsible gambling: limits, self-exclusion, session controls — passed as ticket context | per-ticket limits, acceptance delay, suspensions, breakers, kill switches |
| geofencing of your players | jurisdiction control on which markets an operator may serve |
| your terms and dispute handling | settlement integrity: signed evidence frames, frozen rule hashes, replayable resolutions, a void policy that refunds rather than guesses |
Regulatory classification of camera-resolved event contracts differs by jurisdiction and is worked through per market with your legal team; Lukk carries supplier KYB, licensing and certification tracks on its side.
Certification, operations and commercials
- Certification runs as a play-money account on the production surface: a disabled-for-real-money operator with an internal play balance, or with your own wallet endpoints pointed at a staging ledger — the full surface, no real money. A dedicated sandbox host with scripted scenarios is on the roadmap.
- Environments. One production host per Lukk deployment; the launch URL tells the widget which API it belongs to, so nothing is hard-coded on your side.
- Keys and secrets rotate on request; a new webhook secret is minted whenever the webhook URL is set.
- Commercials. Revenue share — 5–8% of GGR — with no upfront fees. You set your own stake, payout and position limits and choose which channels and markets to offer.
- Support. Integration questions, certification and incidents: hello@adkuu.com. The account team shares the risk parameter set under NDA if your trading team needs to model against it.
Roadmap
- A dedicated sandbox host with scripted scenarios (forced resolution, void, stream loss, breaker).
- Bet-placed and bet-cancelled webhooks in addition to settlement.
- Session-level limits and reality-check hooks passed at launch (loss limit, session time), on top of the per-ticket limits enforced now.
- Operator-owned cameras and exclusive low-latency streams; partner scene packs.
- Backoffice self-service for branding, presets and limits.
- A localised widget: the widget and its market questions are in English today; the
localeyou pass at session mint is already accepted.
Integration checklist
- Receive operator id, API key and webhook secret; agree currency, mode, margin and limits.
- Register
embed_origins(production and staging sites). - Implement
/debit,/credit,/rollback,/reconcile; verifyX-Lukk-Signature; dedupe onidem_key; answer debits in under 5 s. - Mint launch sessions from your backend; frame the
launch_url; handlelukk:bet,lukk:session_expired/lukk:relaunch_request,lukk:error. - Load your theme and, if you offer dark and light modes, wire
lukk:theme. - Show the player's balance in your chrome; open your deposit flow on
insufficient_funds. - Receive settlement webhooks (verify, dedupe on
bet_id) and/or pull settlements; show won / lost / refunded. - Reconcile daily; compare against
/wallet/statement. - Certify on the play-money account; then go live.
Ready to talk? Write to hello@adkuu.com with your platform, markets and licences, and whether you want the widget, the feed or both. See it running first in Adkuu Play.
Frequently asked questions
How long does a Lukk integration take?
The widget path takes an afternoon: mint a launch session from your backend, frame the returned URL, and implement four wallet endpoints. The feed path, where you build your own UI on the market feed, takes days.
Does Lukk hold player funds?
No. Lukk moves money against the operator's wallet API per transaction — debit, credit, rollback and a daily reconcile — signed with HMAC-SHA256 and idempotent on every call. Lukk never sees a name, an email or a balance.
What does Lukk cost an operator?
Revenue share, 5–8% of GGR, with no upfront fees.
How is Lukk certified?
On a play-money account on the production surface — a disabled-for-real-money operator with the full surface and no real money. A dedicated sandbox host is on the roadmap.