Free key: real listings for yesterday and today, 500 calls a day, no card148 countriesGet yours in 30 seconds
tvguideapi

Last 30 days

API uptimefrom the monitorIncidentsfrom the monitor
All systems

Working normally

Checked every minute from outside our own servers.

Lab/PHP starter

TV Guide API PHP starter

TV listings in your PHP app in five minutes.

A small client that handles keys, errors and rate limits, and two scripts that already work: what is on now in any country, and any channel's day in local time. Copy them, set your key, run.

Lines76
Needscurl
Channels41,066
Free key500 calls a day
Terminalphp now.php GB
$ php now.php GB
4seven                   Gogglebox                            22:00 The Great British Bake Off
5Action                  Police Interceptors                  22:00 Highway Thru Hell
5SELECT                  Warship: Life in the Royal Navy      22:00 Battlefront - WWII: Road To Victory
5STAR                    Ambulance: Code Red                  22:00 A&E After Dark
5USA                     Wild Cards                           22:00 Law & Order: Special Victims Unit
8 Out Of 10 Cats         Episode 5                            22:02 Episode 4
African Movie Channel Se Lodge 49                             22:10 Lodge 49
Ahlebait TV              Preaching of Ahlebait (a.s)          22:00 Islamic Movie
Akaal Channel            Live: Sikligar Wanjare Gurdwara      22:25 Today's Sikh History
Alb UK TV                Programi i ALB UK                    23:00 Programi i ALB UK
Quick startFour steps, about five minutes
1Get a free keyWith Google, in a minute. No card.tvguideapi.com/login
2Check the one thing it needsPHP 8.1 or later with curl.php -m | grep curl
3Set your keyKeep it out of your code, in the environment.export TVG_KEY=tvg_live_...
4Run itAny country code, and your time zone.php now.php GB Europe/London
The starterThree files that work as they are

A client, a now-and-next script and a schedule script. The Output tab is what php now.php GB printed a few minutes ago, from the live guide.

Get a free key
<?php
// tvguide.php: a small client for the TV Guide API. PHP 8.1+, the curl extension only.
final class TvGuide
{
    public function __construct(private string $key, private string $base = 'https://api.tvguideapi.com') {}

    public function get(string $path, array $query = []): array
    {
        for ($try = 1; ; $try++) {
            $ch = curl_init($this->base . $path . ($query ? '?' . http_build_query($query) : ''));
            curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_TIMEOUT => 20,
                CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $this->key, 'Accept: application/json']]);
            $raw = curl_exec($ch);
            if ($raw === false) throw new RuntimeException(curl_error($ch));
            $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
            $size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            $body = json_decode(substr($raw, $size), true) ?? [];
            if ($code === 429 && $try < 3) {
                // wait as long as the API asks, then try again
                preg_match('/^retry-after:\s*(\d+)/mi', substr($raw, 0, $size), $m);
                sleep((int) ($m[1] ?? 2));
                continue;
            }
            if ($code >= 400) throw new RuntimeException(($body['error']['code'] ?? 'http_' . $code) . ': ' . ($body['error']['message'] ?? 'request failed'));
            return $body;
        }
    }

    /** Channel names by id, for one country. */
    public function channelNames(string $country): array
    {
        $names = [];
        foreach ($this->get('/v1/channels', ['country' => $country, 'limit' => 500])['data'] as $c) $names[$c['id']] = $c['name'];
        return $names;
    }

    public function findChannel(string $name, ?string $country = null): ?array
    {
        return $this->get('/v1/channels/search', array_filter(['q' => $name, 'country' => $country]))['data'][0] ?? null;
    }
}
Runs on the free keyHandles 429 and Retry-AfterErrors with their code
RecipesEight jobs, a few lines each

Built on the client above. Each opens its endpoint in the documentation, with Try it.

Every endpoint
In productionSix rules that keep an app fast and polite
UTCEvery time comes in UTC. Convert at the edge, with DateTimeZone, and pass tz to cut a local day.
IdsChannel, show and episode ids never change. Look them up once and store them.
CacheA day's schedule changes rarely. Fetch it every 10 to 30 minutes, not on every page view.
429Over your rate, the API says so and sends Retry-After. The client above waits and tries again.
HeadersX-RateLimit-Remaining and X-Quota-Remaining tell you what is left before you hit a limit.
ErrorsEvery error is {"error": {"code", "message", "doc_url"}}: show the message, log the code.
What comes backThe answer behind the script

The same shape for every country. Fields in full on Now on.

{
    "data": [
        {
            "channel": "ch_...",
            "now": {
                "title": "Gogglebox"
            },
            "next": {
                "title": "The Great British Bake Off",
                "local_start": "22:00"
            }
        },
        {
            "channel": "ch_...",
            "now": {
                "title": "Police Interceptors"
            },
            "next": {
                "title": "Highway Thru Hell",
                "local_start": "22:00"
            }
        }
    ],
    "meta": {
        "count": 10
    }
}
Real titles from a few minutes agoFields trimmed
AAlso in PythonThe same starter in the other language.The Python starter
BOr let an assistant do itClaude, Cursor and other assistants call the API through the MCP server.The MCP server
CTry any call firstEvery endpoint runs live in the documentation, with your key remembered.The documentation
DA whole country as XMLTVFor media centres and IPTV players.The XMLTV builder
PlansBuild on the free key, ship on a plan

Everything above except sport, XMLTV and the archive runs on the free key.

Free key$0 for everReal listings for yesterday and today.
  • Listings, now and next, channels
  • Every country
  • MCP on your key
Get a free key
LiveMost chosen$39 a monthEvery endpoint today and ahead, for live products.
  • Everything in Free key
  • Shows, episodes and films
  • Sport, live told apart from repeats
  • XMLTV exports
Choose Live
Archive$79 a monthPast schedules and the episode archive.
  • Everything in Live
  • Listings back to 2010
  • Episodes back to 1908
  • 2 keys
Choose Archive
Complete$249 a monthEverything, in bulk, for products built on it.
  • Everything in Archive
  • XMLTV and CSV exports
  • 5 keys
  • Highest limits
Choose Complete
Your PHP app, with every channel, tonight

A free key in a minute, with Google. No card. 41,066 channels in 155 countries.