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
🔗 Endpoints
| URL | What |
|---|---|
https://epgtalk.com/api/now/combined.json | Every 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.json | Same, for each of the other guides |
https://epgtalk.com/api/tonight.json | Tonight's Picks: big games, premieres, new episodes and movies for the next ~36 hours |
https://epgtalk.com/api/index.json | List 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.