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.
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>
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… | Type | What 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. |
https://tv.jalowin.com · Every endpoint takes
?token=YOUR_TOKEN — plus &sig=… if your token is signed.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.
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' }
);
ip. It's what binds playback to the viewer's network.
Leave it out and the embed URL replays from anywhere until the JWT expires — we can't
enforce what you don't sign.expiresIn short — 2h covers a full game with room to spare.
sig alongside the tokenAnywhere 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
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).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>
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:
embed URL for each match is returned by the API in the
embed field — you can use it directly.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
}
| Field | Meaning |
|---|---|
id | Unique match id (the number is the ESPN event id). Use it for the embed. |
watchable | true when the game is live and a channel is available — only then is it playable. |
embed | Ready-to-use iframe URL for that single match. |
espn.state | pre (upcoming) · in (live) · post (finished). |
espn.away/home | Team name, logo, live score, brand color. |
feeds[].play | Direct HLS (.m3u8) URL — for your own player (headless). |
To show the live stream next to your odds for a given event:
GET /api/public/events?token=... (every ~30s).id
(if your data uses ESPN). Example: your "Orioles vs White Sox" → our g-401815964.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>
feeds[].play HLS only if you run your own video player.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).