Jalowin•TV Integration Guide

Embed live sports into your website or app. Two ways: a full sports catalog widget, or a single-match player to place next to your betting markets (sportsbook style). Plus a simple REST API for programmatic integration.

⚡ Quick start — paste these two lines where you want the live-sports board, replacing YOUR_TOKEN with the token we give you. That's it.
<div id="jalowin-tv" data-token="YOUR_TOKEN" data-height="640"></div>
<script src="https://tv.jalowin.com/widget/embed.js" async></script>
Did we also send you a secret? Then you have a signed token and it needs one more attribute — Section 2 — otherwise the player stays black.
Contents 1. Getting started — which token do you have? 2. Signed tokens (🔒 read first if you have a secret) 3. Full catalog widget 4. Single-match embed (sportsbooks) 5. REST API 6. Sportsbook flow (match → embed) 7. Customization & security

1. Getting started

You need an access token from Jalowin•TV. It comes in one of two types — check which one we gave you, because everything else depends on it:

We sent you…TypeWhat it means
An integration ID and a secret 🔒 Signed Works on any of your domains — no list to maintain. Your backend must sign a short JWT per viewer: Section 2. The ID on its own will not play.
Just a token 🌐 Domain-locked Works only on the domains you gave us, and nowhere else. Nothing extra to do — skip to Section 3.
Base URL: https://tv.jalowin.com · Every endpoint takes ?token=YOUR_TOKENplus &sig=… if your token is signed.

2. Signed tokens 🔒

Built for sportsbooks and PPH networks: because we trust the signature instead of the domain, one integration covers hundreds of agent sites and you never have to send us a domain list. A copied link stops playing.

Skip this section entirely if we didn't give you a secret.

Step 1 — sign a JWT on your backend, one per viewer

The secret stays on your server. It must never reach the browser: anyone who reads it can mint their own access.

import jwt from 'jsonwebtoken';

const sig = jwt.sign(
  { iss: INTEGRATION_ID, ip: viewerIp },   // viewerIp = public IP of the person watching
  process.env.JALOWIN_SECRET,              // the secret we gave you — server-side only
  { algorithm: 'HS256', expiresIn: '2h' }
);
Two things that decide whether this is actually secure: Keep expiresIn short — 2h covers a full game with room to spare.

Step 2 — pass sig alongside the token

Anywhere this guide shows ?token=YOUR_TOKEN, add &sig=. For the catalog widget, use data-sig:

<div id="jalowin-tv" data-token="INTEGRATION_ID" data-sig="<%= sig %>" data-height="640"></div>
<script src="https://tv.jalowin.com/widget/embed.js" async></script>

For a single match, and for the API:

<iframe src="https://tv.jalowin.com/widget/match.html?token=INTEGRATION_ID&sig=SIG&id=MATCH_ID"
        width="100%" height="220" frameborder="0"
        allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>

GET https://tv.jalowin.com/api/public/events?token=INTEGRATION_ID&sig=SIG
Call the API with your sig and the embed URL of every match comes back already signed — drop it straight into an iframe, nothing to append. That's the whole sportsbook flow (Section 6).

What you get

3. Full catalog widget

Shows the full live-sports board (all sports, scores, schedule). Best for a dedicated "Live Sports" page. Add two lines:

<div id="jalowin-tv" data-token="YOUR_TOKEN" data-height="640"></div>
<script src="https://tv.jalowin.com/widget/embed.js" async></script>

Or a direct iframe:

<iframe src="https://tv.jalowin.com/widget/events.html?token=YOUR_TOKEN"
        width="100%" height="640" frameborder="0"
        allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>

4. Single-match embed (sportsbooks)

Embed one specific live game — ideal next to odds/markets, like Stake or DraftKings. You pass the id of the match (from the API, see below):

<iframe src="https://tv.jalowin.com/widget/match.html?token=YOUR_TOKEN&id=MATCH_ID"
        width="100%" height="220" frameborder="0"
        allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>

The single-match player automatically:

The exact embed URL for each match is returned by the API in the embed field — you can use it directly.

5. REST API

GET /api/public/events

Returns the day's sports, each with its matches (live, upcoming, finished today).

GET https://tv.jalowin.com/api/public/events?token=YOUR_TOKEN

Response (simplified):

{
  "sports": [
    {
      "key": "MLB", "label": "MLB · Baseball", "emoji": "⚾",
      "leagueLogo": "https://a.espncdn.com/...",
      "matches": [
        {
          "id": "g-401815964",
          "title": "Chicago White Sox @ Baltimore Orioles",
          "watchable": true,                       // live AND has a channel
          "embed": "https://tv.jalowin.com/widget/match.html?token=...&id=g-401815964",
          "espn": {
            "state": "in",                         // pre | in | post
            "status": "Top 5th",
            "startTime": "2026-06-30T22:35Z",
            "away": { "name": "Chicago White Sox", "logo": "...", "score": "3", "color": "#000000" },
            "home": { "name": "Baltimore Orioles", "logo": "...", "score": "2", "color": "#df4601" }
          },
          "feeds": [
            { "channelId": 127, "label": "MASN Baltimore", "lang": "en",
              "play": "https://tv.jalowin.com/live/127/index.m3u8?token=..." }
          ]
        }
      ]
    }
  ],
  "sportCount": 3, "matchCount": 19
}

Key fields

FieldMeaning
idUnique match id (the number is the ESPN event id). Use it for the embed.
watchabletrue when the game is live and a channel is available — only then is it playable.
embedReady-to-use iframe URL for that single match.
espn.statepre (upcoming) · in (live) · post (finished).
espn.away/homeTeam name, logo, live score, brand color.
feeds[].playDirect HLS (.m3u8) URL — for your own player (headless).

6. Sportsbook flow (match → embed)

To show the live stream next to your odds for a given event:

  1. Poll GET /api/public/events?token=... (every ~30s).
  2. Match your event to ours — by team names, league, or the ESPN id in id (if your data uses ESPN). Example: your "Orioles vs White Sox" → our g-401815964.
  3. When watchable === true, render the embed next to your markets:
    <iframe src="{match.embed}" width="100%" height="220"
            frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>
  4. Before it's live, show your own "Starts at {espn.startTime}" — or embed anyway and the player shows the countdown and starts automatically.
Prefer the iframe embed (handles autoplay, failover, mobile, score overlay for you). Use the raw feeds[].play HLS only if you run your own video player.

7. Customization & security

Per-client We can configure your token to show only certain sports and to use your accent color, so the player matches your brand. Just ask.

Concurrency Each integration can carry a cap on simultaneous viewers. Over it, playback returns 429 — tell us the ceiling you need.

Which mode? Domain-locked if you have a handful of fixed sites and no backend to sign with. Signed (Section 2) for anything with many domains or real money on the stream — it's the only mode where a leaked URL stops working. Whichever you have, we already picked it with you; you don't need to choose here.

Copied links The video URLs we hand your player are always tied to the viewer's IP and channel, and expire — so a stolen .m3u8 won't play elsewhere, in either mode. In signed mode that protection extends to the embed itself, as long as you sign the ip claim (Section 2).

Autoplay Browsers require muted autoplay — the player starts muted with a "Tap to unmute" button (standard for embedded video).