← TG TVDeveloper docs

TG TV API & Embeds

Every channel is available as JSON and as a ready-to-iframe player page. No API key needed — endpoints are open with CORS enabled.

Embed a channel

Drop this anywhere on your site. Replace 143 with any channel id.

<iframe
  src="https://your-site.lovable.app/embed/143"
  width="100%" height="480"
  frameborder="0" allowfullscreen
  allow="autoplay; fullscreen; encrypted-media; picture-in-picture">
</iframe>

Responsive 16:9 version:

<div style="position:relative;padding-top:56.25%">
  <iframe src="https://your-site.lovable.app/embed/143"
    style="position:absolute;inset:0;width:100%;height:100%;border:0"
    allowfullscreen allow="autoplay; fullscreen; encrypted-media"></iframe>
</div>

GET /api/public/channels

Full channel list with ids, names, categories, logos and links. Optional query params: category, q (name search).

curl "https://your-site.lovable.app/api/public/channels?category=Sports&q=star"
{
  "count": 1,
  "channels": [
    {
      "id": "143",
      "name": "CNBC TV18 Prime",
      "category": "English",
      "logo": "https://…/CNBCTV18Prime.png",
      "embed": "https://your-site.lovable.app/embed/143",
      "watch": "https://your-site.lovable.app/watch/143"
    }
  ]
}

GET /api/public/channels/{id}

Resolves one channel into playable sources: signed manifest URL(s) plus ClearKey DRM values when the stream is encrypted. Tokens are short-lived, so call it right before playback.

curl "https://your-site.lovable.app/api/public/channels/143"
{
  "id": "143",
  "name": "CNBC TV18 Prime",
  "category": "English",
  "sources": ["https://…/index.mpd?__hdnea__=…"],
  "drm": { "type": "clearkey", "keyId": "eb19…", "key": "b279…" },
  "embed": "https://your-site.lovable.app/embed/143"
}

Play it in your own player

Any MPEG-DASH player with ClearKey support works — here with Shaka Player.

const res = await fetch("https://your-site.lovable.app/api/public/channels/143");
const ch = await res.json();

const player = new shaka.Player();
await player.attach(document.querySelector("video"));
if (ch.drm) player.configure({ drm: { clearKeys: { [ch.drm.keyId]: ch.drm.key } } });
await player.load(ch.sources[0]);

V2 API (24/7 channels)

A second catalogue of 900+ always-on channels. Same open, CORS-enabled style as V1, but HLS-based and with multiple servers per channel. Every server comes back as a relay URL you can hand straight to any HLS player.

GET /api/public/v2/channels

Full 24/7 channel list. Optional query param: q (name search).

curl "https://your-site.lovable.app/api/public/v2/channels?q=abc"
{
  "version": 2,
  "count": 1,
  "channels": [
    {
      "id": "51",
      "name": "ABC USA",
      "stream": "https://your-site.lovable.app/api/public/v2/channels/51",
      "watch": "https://your-site.lovable.app/v2/watch/51",
      "embed": "https://your-site.lovable.app/v2/embed/51"
    }
  ]
}

GET /api/public/v2/channels/{id}

Resolves one channel into every working server. Each playable link is a relay on this site, so it works cross-origin with no extra headers.

curl "https://your-site.lovable.app/api/public/v2/channels/51"
{
  "version": 2,
  "id": "51",
  "name": "ABC USA",
  "watch": "https://your-site.lovable.app/v2/watch/51",
  "embed": "https://your-site.lovable.app/v2/embed/51",
  "servers": [
    {
      "key": "ws1",
      "label": "Server 1",
      "type": "hls",
      "playable": "https://your-site.lovable.app/api/public/v2/proxy?u=…&r=…"
    }
  ]
}

Embed a V2 channel

The embed page has the server switcher built into the player, so viewers can change server themselves.

<div style="position:relative;padding-top:56.25%">
  <iframe src="https://your-site.lovable.app/v2/embed/51"
    style="position:absolute;inset:0;width:100%;height:100%;border:0"
    allowfullscreen allow="autoplay; fullscreen; encrypted-media"></iframe>
</div>

Play V2 in your own player

The relay returns a normal HLS playlist — hls.js, Shaka, Video.js or native Safari all work.

const res = await fetch("https://your-site.lovable.app/api/public/v2/channels/51");
const ch = await res.json();

const hls = new Hls();
hls.loadSource(ch.servers[0].playable);
hls.attachMedia(document.querySelector("video"));

V2 notes & limits

  • Only servers verified as playable at request time are returned.
  • Server links are signed and short-lived — refetch instead of storing them.
  • Some channels have no live server at all; that returns 404.
  • Caching: 5 min for the list, 30 s for a channel.

Notes & limits

  • Streams are geo-restricted to India by the upstream CDN.
  • Signed tokens expire within minutes — refetch instead of caching sources.
  • Responses are cached briefly (5 min for the list, 1 min for a channel).
  • Status codes: 400 bad id, 404 unknown channel, 502 upstream down.