Public JSON

Free, no key, no sign-up: what's on now and next on every EPGTalk channel, plus Tonight's Picks — for Home Assistant, Kodi skins, dashboards, Discord bots and your own apps.

⚡ Try it

Pick a channel to see what the JSON says is on.

🔗 Endpoints

URLWhat
https://epgtalk.com/api/now/combined.jsonEvery channel in the Combined guide, from 1 hour ago to 10 hours ahead
…/api/now/us.json · uk.json · latino.json · uslocal.json · sports.json · freetv.jsonSame, for each of the other guides
https://epgtalk.com/api/tonight.jsonTonight's Picks: big games, premieres, new episodes and movies for the next ~36 hours
https://epgtalk.com/api/index.jsonList of all endpoints and when they were last updated

Files refresh about every 6 hours (full 7-day guides every 2 days). They hold a schedule, not a single "now" value — pick the current show by comparing start / stop (unix seconds, UTC) with your clock. CORS is open, so browsers can fetch them directly.

🧾 Fields

{
  "guide": "Combined", "updated": "2026-10-03T11:57:02-05:00",
  "from": "2026-10-03T15:57:02Z", "until": "2026-10-04T02:57:02Z",
  "channels": [
    { "name": "ESPN US", "number": "206", "logo": "https://…",
      "programmes": [
        { "start": 1791043200, "stop": 1791054000, "title": "College Football",
          "subtitle": "Notre Dame at North Carolina", "episode": "S01E05",
          "type": "sports",            // sports | movie | news | kids (when known)
          "new": true, "live": true,   // only present when true
          "image": "https://…" } ] } ] }

🏠 Home Assistant

Shows what's on one channel right now. Add to configuration.yaml, change ESPN US to any channel name from the Try it box, and restart.

rest:
  - resource: https://epgtalk.com/api/now/combined.json
    scan_interval: 1800
    sensor:
      - name: "EPGTalk ESPN"
        value_template: "{{ value_json.updated }}"
        json_attributes_path: "$.channels[?(@.name=='ESPN US')]"
        json_attributes:
          - name
          - logo
          - programmes

template:
  - sensor:
      - name: "On ESPN now"
        state: >
          {% set t = now().timestamp() %}
          {% set p = state_attr('sensor.epgtalk_espn', 'programmes') or [] %}
          {% set cur = p | selectattr('start', 'le', t) | selectattr('stop', 'gt', t) | list %}
          {{ (cur[0].title ~ (' — ' ~ cur[0].subtitle if cur[0].subtitle else ''))[:255] if cur else 'Off air' }}
        attributes:
          next: >
            {% set t = now().timestamp() %}
            {% set p = state_attr('sensor.epgtalk_espn', 'programmes') or [] %}
            {% set nx = p | selectattr('start', 'gt', t) | list %}
            {{ nx[0].title if nx else '' }}
        picture: "{{ state_attr('sensor.epgtalk_espn', 'logo') }}"

🎬 Kodi

Skins and add-ons can read the same files with any web request — for example a widget that shows Tonight's Picks from api/tonight.json. For the TV guide itself, Kodi should keep using the XMLTV guide with PVR IPTV Simple Client (see Player Setup).

💻 JavaScript / Python

// what's on every channel whose name contains "ESPN", right now
const j = await (await fetch('https://epgtalk.com/api/now/combined.json')).json();
const t = Date.now() / 1000;
for (const ch of j.channels.filter(c => c.name.includes('ESPN')))
  console.log(ch.name, '→', ch.programmes.find(p => p.start <= t && p.stop > t)?.title);
import json, time, urllib.request
picks = json.load(urllib.request.urlopen("https://epgtalk.com/api/tonight.json"))["picks"]
for p in picks:
    if p["type"] == "sports" and p["start"] > time.time():
        print(p["start_iso"], p["title"], p.get("tv", ""))

🤝 Fair use

Free for personal and community projects. Please cache — there's nothing new more often than every 6 hours, so polling every 15–30 minutes is plenty. Season/episode numbers are partly from TVmaze (CC BY-SA). Questions or ideas: support@epgtalk.com.