Skip to content
  • There are no suggestions because the search field is empty.

Oddin.gg Ghost documentation

Introduction

Oddin.gg Ghost is a real-time, interactive 3D visualization of live Counter-Strike 2 (CS2) matches, designed to enhance engagement with immersive match views.

Ghost comes in two integration variants:

  • Ghost — game visualization only (no betting UI)
  • Betpeek — full experience including betting iframe, selections, wallet API, and risk management overlay

Ghost can be embedded in partner frontends using URLs served from Oddin’s CDN, while Betpeek is integrated via Oddin’s turnkey iframe solution.

1. Supported Esports

Esport BetPeek
Counter-Strike 2* ✅
Dota 2* ✅

*Duels products are not supported

2. Ghost vs Betpeek

Feature Ghost Betpeek
Game Visualization ✅ ✅
Betting Overlay (stakes, selections, wallet) ❌ ✅
Authentication Token-based (per match / partner) Token + Player session
API Interaction gRPC call to retrieve Ghost URL Integrated via Oddin iFrame
Embedding Partner embeds directly from CDN Oddin-hosted iFrame
Fullscreen Support ✅
Desktop & Mobile
✅
Desktop & Mobile

ℹ Ghost is typically used when partners handle UI, wallet, and betting independently, and only need the in-game 3D visualization.

This documentation describes the integration process for Ghost (non-betting UI). For the full experience including betting overlay, please consult Oddin.gg’s BetPeek documentation.

3. Authentication & Access Control

3.1. Environments

We currently provide two different environments – Production and Integration. The Production environment is intended to be used only when you are finished with the integration and ready to go live. Please use the Integration environment for all testing and integration purposes.

You can find the endpoint for each environment in the following table:

Environment API URL
Production api-ghost-grpc.oddin.gg
Integration api-ghost-grpc-integration.oddin.gg

3.2. URL Retrieval

  • Ghost URLs are retrieved via gRPC, not hardcoded.
  • The partner calls the GetMatchInfo method using:
    • match_id
    • client_token
  • The API validates:
    • The token
    • The IP/domain whitelist. We will require a full list of IPs to be whitelisted, including ones used for staging/integration.

3.3. Example gRPC Schema

service Ghost {
rpc GetMatchInfo(MatchInfoRequest) returns (MatchInfoResponse);
rpc GetMatchStatus(MatchStatusRequest) returns (MatchStatusResponse);
}
message CS2MatchInfoResponse {
string map_name = 2;
string map_asset_name = 3;
string game_version = 4;
string asset_url = 5; // Specifies the URL for the asset of the match.
}

3.4. Public Access Rules

  • For Ghost, you can share the same generated link publicly (token-authenticated at backend level).
  • Authentication happens server-side (when retrieving the Ghost URL), not per player/user.

4. CDN URL Format

Each Ghost visualization is hosted on Oddin’s CDN and follows this pattern, which corresponds to the asset_url from MatchInfoResponse:

<https://cdn.oddin.gg/ghost-assets/v1.0.5/map/{map_asset_name}/Oddin-HTML5-Shipping.html?X-MatchURN={match_urn}&url={data_api_url}&token={access_token}>

4.1. Parameters

Parameter Description Example
v1.0.5 Version tag for caching and asset stability /v1.0.5/
map_asset_name Map identifier (from the API, no de_ prefix) mirage, ancient, dust2
X-MatchURN Match ID from Oddin Odds feed 1895759
url Data API endpoint https://api-ghost-integration.oddin.gg
token Partner’s assigned Ghost token a0a0a000-000a-000a-0aa0-0000000aa00a
lang Language parameter
(currently supported: English - en, Russian - ru)
en

5. Polling Logic & Match Lifecycle

Ghost availability is discovered after the match goes live, by using the Oddin Odds Feed (similar to Disir/live widgets integrations).

5.1. Workflow

  1. Detect OnFixtureChange → Match goes Live.
  2. Poll api-ghost-grpc-integration.oddin.gg for MatchStatus. This indicates whether the live match supports Ghost.
  3. When Available, get CDN URL from GetMatchInfo and display Ghost inside your own iFrame.
  4. Ghost automatically transitions between maps during the match while the application is active.

5.2. Polling Intervals

Parameter Description Example
MatchStatus Detect match availability Every 10–30 seconds once the match goes live
MatchInfo Get current map name On new map start only

Polling during map transitions can be reduced. Cache the map info until the Odds Feed indicates a new map start.

6. Detecting Map Transitions (CS2)

Use the Odds Feed to identify when a new map begins.

6.1. Correct Trigger

Map transitions should be based on scoreboard activity, not just PeriodScores.

When the <scoreboard> data appears with current_round="1", the new map has officially started. This appears only when the first round actually starts and the timer starts ticking.

<scoreboard current_ct_team="2" home_won_rounds="0" away_won_rounds="0" current_round="1"></scoreboard>

6.2. Common Mistake

Polling on PeriodScores change may occur before the new map is live, resulting in reusing the old URL.

7. Embedding & Frontend Guidelines

  • The Ghost client should be embedded in your platform using a standard <iframe> element.
  • The CDN URL is the iFrame source.
  • Partners are responsible for layout and UX integration.

7.1. Recommended Display Sizes

Device Minimum size Notes
Desktop 640×320 px Readable UI, no scrollbars
Mobile Fullscreen modal Suboptimal in small containers

7.2. Suggested Behavior

  • Desktop: Show Ghost in theatre mode, or with the modal with the option to go fullscreen.
  • Mobile: Trigger the fullscreen modal directly when the Ghost (or some other suggestive button name e.g. “3D Live”) button is pressed.

Example UX flow:

  1. User opens match details.
  2. User clicks “3D Live” → Ghost modal appears.
  3. User can switch to fullscreen → returns to modal on exit.

7.3. Handling Fullscreen & iOS Limitations

  • On desktop, the embedded iframe can display the live mode directly.
  • On mobile, opening Ghost in fullscreen provides the best experience.
  • iOS does not support the standard fullscreen API. In this case:
    • Implement a custom overlay to simulate fullscreen behavior.
    • Disable allowfullscreen on the <iframe> element, since the Ghost engine triggers fullscreen internally and your overlay would otherwise be hidden.
  • To handle fullscreen toggling or exit events between the iframe and the host page, use a toggle-fullscreen message:

// Inside the iframe

window.parent.postMessage({ type: 'toggle-fullscreen' }, '*')

// In React (host page)

useEffect(() => {

const handleMessage = (event) => {

if (event.data.type === 'toggle-fullscreen') onToggleFullscreen?.()

}

window.addEventListener('message', handleMessage)

return () => window.removeEventListener('message', handleMessage)

}, [onToggleFullscreen])


This allows the host app to control custom overlays or close fullscreen mode gracefully, even on platforms without fullscreen API support (e.g., iOS).

8. Supported Sports

Sport URN Description Ghost Support
od:sport:3 Counter-Strike 2 ✅ Supported
od:sport:21 CS2 Duels ❌ Not supported
od:sport:2 Dota 2 Coming soon

Only od:sport:3 should be considered Ghost-eligible for the time being.

9. Error Handling

Error Cause Resolution
Access Denied Missing or malformed url parameter Add proper API URL
Not_found API mismatch Fixed: now returns Unavailable
StatusCode="Internal" Unsupported sport Filter CS2 only
MATCH_STATUS_UNAVAILABLE Wrong environment or inactive match Verify endpoint, token, and match status

10. Environments

Ensure each environment (integration, production) is configured with:

  • Correct API URLs
  • Whitelisted domains/IPs

If the staging environment receives no Ghost URLs, ensure the match belongs to a supported sport and that the environment permissions match your integration setup.

11. Summary of Best Practices

  • Authenticate via the backend token and IP whitelist
  • Filter for od:sport:3 only
  • Detect new maps using Odds Feed scoreboard events
  • Poll MatchStatus every 10–30s
  • Fetch new map URLs only when round 1 starts
  • Embed Ghost at minimum 640×320 px, but fullscreen with tailor made odds overlays is preferred for optimum UX
  • Use fullscreen for mobile
  • Cache URL per map, refresh on reload or reconnection