-
Notifications
You must be signed in to change notification settings - Fork 5
API 20141201
Any user with a valid Schedules Direct login may use the API. Developers may send email to grabber@schedulesdirect.org for assistance, but the Developers Corner should be your first stop.
NOTE: our contract with our upstream provider limits us to providing data for individual use only and exclusively to Open Source software; using an open source program as "middleware" and then pushing data into a commercial application violates the terms of service. Please see the subscriber agreement if you have questions. If you would like to use the data in a commercial, academic or governmental environment send an email to Kyle Brownell at Nielsen.
This page describes API version 20141201. Last update: 2025-03-15. See API Updates for details.
The server implements a RESTful interface.
There are multiple tools which can assist if you're implementing a REST client; two good ones are Postman https://www.postman.com/ and JSONlint https://jsonlint.com/
You can also use the mfdb-json PHP scripts at https://github.com/SchedulesDirect/mfdb-json as a starting point.
DateTime responses are in "Z" / UTC time. There are no Daylight Saving Time adjustments made in any DateTime values.
From the outset, the design goals of the JSON API was to minimize the amount of data which needed to be sent from the server to the client. Throughout the API you will see that it makes liberal use of "modified" and MD5 hashes to allow a client to determine if it needs to perform an update on any particular piece of information. To reduce server-side processing Schedules Direct will not maintain a list of channels that you want sent to you; it's up to the client to request what they want when they make the request. (This makes the server architecture almost stateless and allows us to scale easily)
The API architecture allows your client to quickly determine things like:
- Has the lineup mapping (the list of which content is on which channel) for a headend changed? If yes, then the modified date of the lineup will be updated. If your copy has a different modified date, then download the update. (It is still up to your client to determine whether the lineup should be applied automatically, whether you will run a diff of the existing vs. the new)
- Has the schedule for a stationID changed since the last time you downloaded it? If yes, download a new one. Schedule updates happen multiple times per day, but not all schedules may have an update.
- Have their been any updates to the programs in the schedule? The schedule for a stationID will tell you the programID that's in a timeslot, and the MD5 hash of the data for that program. But it doesn't automatically include the program data itself - that's a separate API call. Your application could compare the hash in the schedule with the hash of your local copy of the program data. If the MD5 hash in the schedule data is the same as what you already have from a previous download, then there's nothing to do. Or, the same program is played multiple times in a 2 week period over multiple stationIDs. It will still be the same program, with the same MD5 hash. Your application would only need to download it once as part of a batch request you send to the server for programIDs that you require. If it's different, then there may be new guest stars, or a late-breaking program update has occurred, so your client can include the programID in the batch request of new / updated programIDs.
A headend may contain multiple lineups; a lineup is a specific mapping of channels and stationIDs. For example, for a "Cable" transport lineup, the headend may have three separate lineups: one for analog channels, which don't require a set-top-box, one for digital cable, which does require a set top box, and a QAM lineup, which is content which is available that is digital, but does not require a set-top-box.
Some examples:
- You may have a lineup that doesn't require external hardware in order to tune. For a lineup that uses the transport type "Cable", this would be channels "2" through "125". DVB-C, -S and -T also fall into this category. In the data, these will have a device type of "DEFAULT".
- You may have a digital lineup; one that requires an external set-top-box of some sort. For a cable lineup, most digital lineups are designated with an "X" as the device for historical reasons.
- You may have a QAM lineup; cable TV content which is available with a QAM tuner. The device type would be "QAM".
A client process flow during initial configuration would be:
- Using a web browser, configure an account at the Schedules Direct website. Accept the Terms of Service, etc.
Using a grabber client:
- Set a useragent in the header of your request. The useragent will allow
Schedules Direct and the developers to work together if there are bugs;
please see http://forums.schedulesdirect.org/viewtopic.php?f=17&t=2597
- The useragent must include the version of the software being run; this will allow SchedulesDirect to redirect a subscriber who has opened a support ticket to the latest version of your software.
- Obtain the token for this session. If the token response indicates that the system is offline, you should disconnect. See Obtain a token for examples of success and failure.
- Obtain the current status.
- If the system status is "Offline" then disconnect; all further processing will be rejected at the server. A client should not attempt to reconnect for 1 hour.
- Obtain the list of headends for the postal code.
- Allow the user to select which lineup they want data for. Use the PUT function to add that lineup to their account at Schedules Direct. By default, a user may have 4 lineups in their account, but this can be modified by sending a request through the Schedules Direct ticket service or by sending an email to grabber@schedulesdirect.com
- You may perform 6 "adds" in a 24 hour period. The status response will indicate the number of lineup changes remaining.
- Download the lineup. This will provide the user the mapping of channels, callsigns and stationIDs.
- Allow the user to select which stations they wish to receive data for - this is done at the client; the server does not maintain a list of stations for the user, only the lineup name.
- Send a request for the schedules for those stationID's to the server. You may request the schedule data for all days for the stationID, or a subset. Use the "date" element in the request if you'd like to specify which days to get the schedule for. This can also be used to process data in batches if you have a memory or CPU-limited client.
- Process the schedules; each stationID will typically contain at least 14 days of data. Some stationID's may have more than 14 days; some which are outside of North America may have as little as 7 days if the broadcaster doesn't provide daily updates to our upstream.
- Determine which programID's need to be downloaded. During an initial download, the client will have an empty cache of programID's / MD5 hashes, so the client will need to download all relevant programID's.
NOTE: the server has been successfully tested with over 30,000 programID requests, but the response may overload the client. Therefore there is a hard-coded limit on the server; you may only request 5000 programIDs, schedules, or schedule MD5's per request. (But you may issue multiple requests if you need more than 5000 pieces of information from the server.) There is a 10-minute timeout on the server; if the response to your request can not be sent to you within 10 minutes, it will terminate at the 10 minute point. So, do not request 5000 programIDs if you are on a 33.6Kbps dial-up.
Once the client is in a steady state:
- Obtain the token for this session. If the token response indicates that the system is offline, you should disconnect. See Obtain a token for examples of success and failure.
- Obtain the current status.
- If the system status is "Offline" then disconnect; all further processing will be rejected at the server. A client should not attempt to reconnect for 1 hour.
- Check the status object and determine if any lineups on the server have newer "modified" dates than the one that is on the client. If yes, download the updated lineup.
- If there are no changes to the lineups, send a request to the server for the MD5 hashes of the schedules that you are interested in. If the MD5 hash for the schedule is the same as you have locally cached from your last download, then the schedule on the server hasn't changed and your client should disconnect.
- If the MD5 hash for the schedule is different, then download the schedules that have different hashes.
- Parse the schedule, determine if the MD5 of the program for a particular timeslot has changed. If the programID for a timeslot is the same, but the MD5 has changed, this means that some sort of metadata for that program has been updated.
- Request the "delta" programID's as determined through the MD5 values.
Requesting only stationID's and programID's that the user is interested in will minimize the time and data required in each download. Downloading only schedules and programs that are different than what you have already downloaded will minimize the download time and processing your client must perform.
Data updates occur seven days a week. At a minimum there will be two data refreshes per day. Use of the MD5 for the schedule will allow your client to determine if a particular stationID has an updated schedule. (Not all stationIDs may be refreshed in a particular time block if there are no server-side updates.)
The following examples give some pointers on how to use Postman to step through the tasks that your program must perform in order to use the service.
This is the first thing your client must do; almost all commands require a token in the header or in the request.
A token is valid for 24 hours; any token requests with the same username/password will return the currently valid token.
POST https://json.schedulesdirect.org/20141201/token
with the body (click the "Raw" button) of the POST being:
{"username":"rkulagow@rocketmail.com", "password":"sha1hexpassword"}
The password field is the sha1_hex hash of the user's password, resulting in a 40-character string being passed to the server. The hash must be sent in lowercase.
If you want to request a new token rather than have the API return the existing token, the request should look like this:
{"username":"rkulagow@rocketmail.com", "password":"sha1hexpassword", "newToken":true}
The "newToken" field is a boolean; if it is not included in the request, then the default is false.
Response:
The server will respond with one of the following:
{
"code": 0,
"message": "OK",
"serverID": "AWS-SD-web.1",
"datetime": "2016-08-23T13:55:25Z",
"token": "f3fca79989cafe7dead71beefedc812b",
"tokenExpires": 1741280766
}
NOTE: The tokenExpires field is the UNIX epoch time for when the token will expire.
If the system is unavailable, you will receive:
{
"response": "SERVICE_OFFLINE",
"code": 3000,
"serverID": "20141201.web.1",
"message": "Server offline for maintenance.",
"datetime": "2015-04-23T00:03:32Z",
"token": "CAFEDEADBEEFCAFEDEADBEEFCAFEDEADBEEFCAFE",
"tokenExpires": 0
}
If the service is offline you should disconnect and retry in 30 minutes.
If you receive a valid token, it must be passed to the server as part of the header for all requests.
In the following examples, where you see Token: Required you must send the token in the header or in the request. In POSTman, click "Headers". Set the Header field to "token" (no quotes, lowercase) and the Value field to the token that you retrieved. You may also add ?token= to the request.
NOTE: the server-side program logic performs the following evaluation:
- Was token provided in the request URL?
- No -> Was token provided in the header?
- No -> if token is required, then error
Therefore, if you provide the token in the request and in the header, then the token in the request takes precedence.
GET https://json.schedulesdirect.org/20141201/status
Token: Required
Response:
{
"account": {
"expires": "2015-06-27T22:16:29Z",
"messages": [],
"maxLineups": 255
},
"lineups": [
{
"lineup": "USA-IL57303-X",
"modified": "2015-04-11T21:30:27Z",
"uri": "/20141201/lineups/USA-IL57303-X"
},
{
"lineup": "USA-NY67791-X",
"modified": "2015-04-17T02:45:44Z",
"uri": "/20141201/lineups/USA-NY67791-X"
},
{
"ID": "USA-WI61859-DEFAULT",
"modified": "1970-01-01T00:00:00Z",
"uri": "/20140530/lineups/USA-WI61859-DEFAULT",
"isDeleted": true
}
],
"lastDataUpdate": "2015-04-17T03:36:24Z",
"notifications": [],
"systemStatus": [
{
"date": "2015-03-23T18:47:00Z",
"status": "Online",
"message": "Lineup responses updated. See http://forums.schedulesdirect.org/viewtopic.php?f=17&t=2645&p=8379 for details."
}
],
"serverID": "20141201.web.1",
"datetime": "2016-08-23T13:57:34Z",
"code": 0
"tokenExpires": 1742015156
}
NOTE: The tokenExpires field is the UNIX epoch time for when the token will expire.
NOTE: If a lineup has been marked as deleted at the headend, then your code may wish to notify the user.
Your client may make a request and query the server to determine if it is running the latest client.
GET https://json.schedulesdirect.org/20141201/version/{clientname}
Token: Not Required
For example:
GET https://json.schedulesdirect.org/20141201/version/mfdb-json
Response:
{
"response": "OK",
"code": 0,
"client": "mfdb-json",
"version": "0.11",
"serverID": "20141201.t2.1",
"datetime": "2014-09-22T19:11:38Z"
}
Your code could then compare the version in the response with an internal version and then prompt the user with what they'd like to do next.
Error Response:
{
"response": "UNKNOWN_CLIENT",
"code": 1005,
"serverID": "20141201.t2.1",
"message": "Did not recognize the submitted client.",
"datetime": "2014-09-22T19:39:52Z"
}
NOTE:Developers, please contact grabber@schedulesdirect.org and provide the clientname string and the version that you'd like the server to reply with.
The services offered may change; querying the server will allow your client to make informed choices.
Token: Not Required
For example:
GET https://json.schedulesdirect.org/20141201/available
Response:
[
{
"type": "COUNTRIES",
"description": "List of countries which are available.",
"uri": "/20141201/available/countries"
},
{
"type": "LANGUAGES",
"description": "List of language digraphs and their language names.",
"uri": "/20141201/available/languages"
},
{
"type": "DVB-S",
"description": "List of satellites which are available.",
"uri": "/20141201/available/dvb-s"
},
{
"type": "DVB-T",
"description": "List of Freeview transmitters in a country. Country options: GBR",
"uri": "/20141201/transmitters/{ISO 3166-1 alpha-3}"
}
]
So for example, to see which countries there is data for, your client would:
GET https://json.schedulesdirect.org/20141201/available/countries
And would then parse the response. You are encouraged to not hardcode the list of countries in your application because the list may change.
{
"North America": [
{
"fullName": "United States",
"shortName": "USA",
"postalCodeExample": "12345",
"postalCode": "/\\d{5}/"
},
{
"fullName": "Canada",
"shortName": "CAN",
"postalCodeExample": "K1A0B1",
"postalCode": "/[A-Z]{1}[\\d]{1}[A-Z]{1}[\\d]{1}[A-Z]{1}[\\d]{1}/gm"
}
],
"Europe": [
{
"fullName": "Austria",
"shortName": "AUT",
"postalCodeExample": "6886",
"postalCode": "/\\d{4}/"
},
<snip>
"Latin America": [
{
"fullName": "Argentina",
"shortName": "ARG",
"postalCodeExample": "A4190",
"postalCode": "/[A-Z]\\d{4}/"
},
{
"fullName": "Belize",
"shortName": "BLZ",
"postalCodeExample": "BZ",
"postalCode": "/BZ/",
"onePostalCode": true
},
<snip>
The above example represents a typical response. For Belize, there is only one postal code available - "BZ", and that is what your client would send when performing the next step. The response also indicates an example of a postal code, and a suggested regexp if you would like to check your submission prior to sending it to the server.
Obtaining the list of transmitters rather than postal codes is an alternate means that your client may use, but is dependent on your user's knowing their transmitter.
GET https://json.schedulesdirect.org/20141201/transmitters/GBR
{
"Aberdare": "GBR-0001213-DEFAULT",
"Angus": "GBR-0001219-DEFAULT",
"Beacon Hill": "GBR-0001324-DEFAULT",
"Belmont": "GBR-0001339-DEFAULT",
"Bilsdale": "GBR-0001228-DEFAULT",
"Black Hill": "GBR-0001227-DEFAULT",
"Blaenplwyf": "GBR-0001213-DEFAULT",
"Bluebell Hill": "GBR-0001318-DEFAULT",
"Bressay": "GBR-0001219-DEFAULT",
"Brierley Hill": "GBR-0001335-DEFAULT",
<snip>
GET https://json.schedulesdirect.org/20141201/headends?country=USA&postalcode=60030
Token: Required
The response will be an array of headends. Note that in CA00053 (and others) that there are multiple lineups in the headend.
Also, please see Automapping Lineups for a means to potentially automatically determine the appropriate lineup.
Response:
[
{
"headend": "CA00053",
"transport": "Cable",
"location": "Beverly Hills",
"lineups": [
{
"name": "Time Warner Cable - Cable",
"lineup": "USA-CA00053-DEFAULT",
"uri": "/20141201/lineups/USA-CA00053-DEFAULT"
},
{
"name": "Time Warner Cable - Digital",
"lineup": "USA-CA00053-X",
"uri": "/20141201/lineups/USA-CA00053-X"
}
]
},
{
"headend": "CA61222",
"transport": "Cable",
"location": "Beverly Hills",
"lineups": [
{
"name": "Mulholland Estates - Cable",
"lineup": "USA-CA61222-DEFAULT",
"uri": "/20141201/lineups/USA-CA61222-DEFAULT"
}
]
},
{
"headend": "CA66511",
"transport": "Cable",
"location": "Los Angeles",
"lineups": [
{
"name": "AT&T U-verse TV - Digital",
"lineup": "USA-CA66511-X",
"uri": "/20141201/lineups/USA-CA66511-X"
}
]
},
{
"headend": "CA67309",
"transport": "Cable",
"location": "Westchester",
"lineups": [
{
"name": "Time Warner Cable Sherman Oaks - Cable",
"lineup": "USA-CA67309-DEFAULT",
"uri": "/20141201/lineups/USA-CA67309-DEFAULT"
},
{
"name": "Time Warner Cable Sherman Oaks - Digital",
"lineup": "USA-CA67309-X",
"uri": "/20141201/lineups/USA-CA67309-X"
}
]
},
{
"headend": "CA67310",
"transport": "Cable",
"location": "Eagle Rock",
"lineups": [
{
"name": "Time Warner Cable City of Los Angeles - Cable",
"lineup": "USA-CA67310-DEFAULT",
"uri": "/20141201/lineups/USA-CA67310-DEFAULT"
},
{
"name": "Time Warner Cable City of Los Angeles - Digital",
"lineup": "USA-CA67310-X",
"uri": "/20141201/lineups/USA-CA67310-X"
}
]
},
{
"headend": "DISH803",
"transport": "Satellite",
"location": "Los Angeles",
"lineups": [
{
"name": "DISH Los Angeles - Satellite",
"lineup": "USA-DISH803-DEFAULT",
"uri": "/20141201/lineups/USA-DISH803-DEFAULT"
}
]
},
{
"headend": "DITV803",
"transport": "Satellite",
"location": "Los Angeles",
"lineups": [
{
"name": "DIRECTV Los Angeles - Satellite",
"lineup": "USA-DITV803-DEFAULT",
"uri": "/20141201/lineups/USA-DITV803-DEFAULT"
}
]
},
{
"headend": "90210",
"transport": "Antenna",
"location": "90210",
"lineups": [
{
"name": "Antenna",
"lineup": "USA-OTA-90210",
"uri": "/20141201/lineups/USA-OTA-90210"
}
]
}
]
Use the lineup field obtained from the GET /headends to determine if the selected lineup is the one the user wants.
Token: Required
GET https://json.schedulesdirect.org/20141201/lineups/preview/USA-IL57303-X
Response:
[
{
"channel": "001",
"name": "XFINITY On Demand",
"callsign": "XDM"
},
{
"channel": "002",
"name": "WBBM",
"callsign": "WBBM",
"affiliate": "CBS"
},
{
"channel": "003",
"name": "WJYS",
"callsign": "WJYS"
},
{
"channel": "004",
"name": "WSNS",
"callsign": "WSNS",
"affiliate": "TELE"
},
<snip>
Error Response:
Invalid lineup, hard fail:
{
"response": "INVALID_LINEUP",
"code": 2105,
"serverID": "20141201.web.3",
"message": "The lineup you submitted doesn't exist.",
"datetime": "2017-12-02T05:48:21Z"
}
Use the lineup field obtained from the GET /headends to add the lineup.
Token: Required
The command follows this format:
PUT /lineups/{COUNTRY}-{LINEUP}-{DEVICE}
So, to add IL57303:X in the United States:
PUT https://json.schedulesdirect.org/20141201/lineups/USA-IL57303-X
Response:
{
"response": "OK",
"code": 0,
"serverID": "AWS-SD-web.1",
"message": "Added lineup.",
"changesRemaining": 254,
"datetime": "2014-05-19T20:16:01Z"
}
Error response:
{
"response": "INVALID_LINEUP",
"code": 2105,
"serverID": "20141201.t2.1",
"message": "The lineup you submitted doesn't exist.",
"datetime": "2014-09-20T03:34:25Z"
}
Token: Required
GET https://json.schedulesdirect.org/20141201/lineups
Response:
{
"code": 0,
"serverID": "20141201.web.1",
"datetime": "2015-04-17T14:22:17Z",
"lineups": [
{
"lineup": "GBR-0001317-DEFAULT",
"name": "Freeview - Carlton - LWT (Southeast)",
"transport": "DVB-T",
"location": "London",
"uri": "/20141201/lineups/GBR-0001317-DEFAULT"
},
{
"lineup": "USA-IL57303-X",
"name": "Comcast Waukegan/Lake Forest Area - Digital",
"transport": "Cable",
"location": "Lake Forest",
"uri": "/20141201/lineups/USA-IL57303-X"
},
{
"lineup": "USA-NY67791-X",
"name": "Verizon Fios Queens - Digital",
"transport": "Cable",
"location": "Fresh Meadows",
"uri": "/20141201/lineups/USA-NY67791-X"
},
{
"lineup": "USA-OTA-60030",
"name": "Local Over the Air Broadcast",
"transport": "Antenna",
"location": "60030",
"uri": "/20141201/lineups/USA-OTA-60030"
},
{
"lineup": "USA-WI61859-DEFAULT",
"name": "DELETED LINEUP",
"isDeleted": true
}
]
}
NOTE: If a lineup has been marked as deleted at the server, both the status and the subscribed lineups will indicate "isDeleted" as TRUE. Your application should use this to notify the user that their lineup may no longer be valid.
Transport types your client should expect:
- Antenna - North American ATSC and analog
- Cable - Requires a set-top-box; typically used in North America
- DVB-C
- DVB-S - Freesat
- DVB-T - Freeview
- IPTV - content delivered using IPTV; for example, SiliconDust's HDHomerun Premium TV offering
- Satellite - Requires a set-top-box; typically used in North America
Token: Required
DELETE /lineups/{COUNTRY}-{LINEUP}-{DEVICE}
Example:
DELETE https://json.schedulesdirect.org/20141201/lineups/USA-IL57303-X
Response:
{
"response": "OK",
"code": 0,
"serverID": "AWS-SD-web.1",
"message": "Deleted lineup.",
"changesRemaining": "254",
"datetime": "2014-05-19T20:18:20Z"
}
Token: Required
GET /lineups/{COUNTRY}-{LINEUP}-{DEVICE}
Example:
GET https://json.schedulesdirect.org/20141201/lineups/USA-OTA-90210
Response for an "Antenna" transport type; in this example this lineup is ATSC and contains the uhfVhf channel number and the atscMajor / Minor. A station still transmitting analog would have a uhfVhf, but no Major / Minor.
"map": [
{
"stationID": "19567",
"uhfVhf": 43,
"atscMajor": 2,
"atscMinor": 1
},
{
"stationID": "88571",
"uhfVhf": 43,
"atscMajor": 2,
"atscMinor": 2
},
{
"stationID": "19568",
"uhfVhf": 36,
"atscMajor": 4,
"atscMinor": 1
},
etc.
Digital transports may contain additional information based on user scans submitted to Schedules Direct. If your application would like the extra data, in the header of the request add "verboseMap" and set it to true.
A non-Verbose map would look like:
{
"map": [
{
"stationID": "24326",
"channel": "001"
},
{
"stationID": "17154",
"channel": "002"
}
]
}
A Verbose map would look like this:
{
"map": [
{
"stationID": "24326",
"channel": "001",
"providerCallsign": "BBC ONE South",
"logicalChannelNumber": "1",
"matchType": "providerCallsign"
},
{
"stationID": "17154",
"channel": "002",
"providerCallsign": "BBC TWO",
"logicalChannelNumber": "2",
"matchType": "providerCallsign"
}
]
}
If your application requests a Verbose map and one is not available you will get the non-Verbose map.
A DVB transport will contain additional information (if available) regarding the transport, network and service IDs:
A lineup using DVB-T as a transport will contain:
"map": [
{
"stationID": "30644",
"frequencyHz": 490000000,
"serviceID": 4164,
"networkID": 9018,
"transportID": 4164,
"channel": "1"
},
{
"stationID": "17154",
"frequencyHz": 490000000,
"serviceID": 4287,
"networkID": 9018,
"transportID": 4164,
"channel": "2"
}
A lineup using DVB-C transport will contain the symbolrate field:
"map": [
{
"stationID": "76861",
"frequencyHz": 247500000,
"deliverySystem": "DVB-C",
"modulationSystem": "QAM64",
"symbolrate": 6875,
"serviceID": 101,
"networkID": 65024,
"transportID": 2190,
"channel": "1"
},
{
"stationID": "87792",
"frequencyHz": 594000000,
"deliverySystem": "DVB-C",
"modulationSystem": "QAM64",
"symbolrate": 6875,
"serviceID": 1200,
"networkID": 65024,
"transportID": 2000,
"channel": "2"
}
A DVB-S will contain satellite-specific tuning:
"map": [
{
"stationID": "30455",
"frequencyHz": 10743000000,
"polarization": "H",
"deliverySystem": "DVB-S",
"modulationSystem": "QPSK",
"symbolrate": 22000,
"fec": "5\/6",
"serviceID": 9612,
"networkID": 2,
"transportID": 2043
},
{
"stationID": "48857",
"frequencyHz": 10743000000,
"polarization": "H",
"deliverySystem": "DVB-S",
"modulationSystem": "QPSK",
"symbolrate": 22000,
"fec": "5\/6",
"serviceID": 9614,
"networkID": 2,
"transportID": 2043
}
In a lineup using DVB-S transport, the channel number is simply an integer with no particular significance. In a -C or -T, the channel number is typically the logical channel number as transmitted. If a DVB lineup does not contain the transport triplet then the Schedules Direct service does not have the information yet.
NOTE: Developers, if there's additional information required for tuning, send email to grabber@schedulesdirect.org so that it can be refined.
A "Satellite" or "Cable" lineup for the will have a map that appear like this:
"map": [
{
"stationID": "74348",
"channel": "001"
},
{
"stationID": "11299",
"channel": "002"
}
The channels are presented as strings for future use; channel "numbers" may include hyphens in a future release.
QAM is handled slightly differently; because providers have multiple ways of presenting a QAM lineup, the map has additional information:
"map": [
{
"channel": "55.29",
"virtualChannel": "55.29",
"deliverySystem": "ATSC",
"stationID": "80606",
"channelMajor": 55,
"channelMinor": 29,
"providerCallsign": "FSPLUS",
"matchType": "providerCallsign"
},
{
"channel": "53.23",
"virtualChannel": "53.23",
"deliverySystem": "ATSC",
"stationID": "10153",
"channelMajor": 53,
"channelMinor": 23,
"providerCallsign": "truTV",
"matchType": "providerCallsign"
},
The providerCallsign and matchType fields are hints on how your application can map a raw scan to the data; the providerCallsign is often locally generated by the provider and doesn't match the callsign as defined in the stations array described below.
The other matchType you may see is "channel"; this is used when the providerCallsign is too ambiguous or not provided; you may see the channel as "76-104" for example.
The "channel" field may contain "_", "-" or "." as a separator; your application should normalize the data into whatever is appropriate locally.
After the "map" section comes the station information as an array of stationIDs:
"stations": [
{
"stationID": "20454",
"name": "WBBMDT (WBBM-DT)",
"callsign": "WBBMDT",
"affiliate": "CBS",
"broadcastLanguage": ["en"],
"descriptionLanguage": ["en"],
"broadcaster": {
"city": "Chicago",
"state": "IL",
"postalcode": "60611",
"country": "United States"
},
"stationLogo": [{
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s20454_dark_360w_270h.png",
"height": 270,
"width": 360,
"md5": "2d436ec23a1f59da4b98f981dafdc8bf",
"source": "Gracenote",
"category": "dark"
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s20454_gray_360w_270h.png",
"height": 270,
"width": 360,
"md5": "28de89680dde8501b9ae08d03da212ea",
"source": "Gracenote",
"category": "gray"
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s20454_light_360w_270h.png",
"height": 270,
"width": 360,
"md5": "29d9866d973c81dfea2430f11ef97f16",
"source": "Gracenote",
"category": "light"
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s20454_white_360w_270h.png",
"height": 270,
"width": 360,
"md5": "2d436ec23a1f59da4b98f981dafdc8bf",
"source": "Gracenote",
"category": "white"
}],
"logo": {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s20454_dark_360w_270h.png",
"height": 270,
"width": 360,
"md5": "2d436ec23a1f59da4b98f981dafdc8bf"
}
}
NOTE: the singular "logo" element is end-of-life as of API-20141201 and is retained for backwards compatibility. It will be removed in the next API.
If it exists, the "stationLogo" field contains an array of station logos. If there are multiple logos in the array, they may differ based on color, or the content of the logo itself. For example, if your users complain that the logos "disappear" because they are black on a black background, then your application may want to display one of the alternate logos in the array.
Category | Description |
---|---|
dark | For dark backgrounds. |
gray | Non-color grayscale for light backgrounds. |
light | For light backgrounds. |
white | All white for dark backgrounds. |
If a station is commercial-free, then that will be indicated in the data as the isCommercialFree attribute; the default is "FALSE" and is therefore not included to reduce the size of the data.
NOTE: if you are aware of a commercial-free station and it is not properly tagged in the data then send an email to grabber@schedulesdirect.org
{
"stationID": "44023",
"name": "KVCRDT (KVCR-DT)",
"callsign": "KVCRDT",
"affiliate": "PBS",
"broadcastLanguage": ["en"],
"descriptionLanguage": ["en"],
"broadcaster": {
"city": "San Bernardino",
"state": "CA",
"postalcode": "92401",
"country": "United States"
},
"isCommercialFree": true,
"stationLogo": [{
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s32356_h3_aa.png",
"height": 270,
"width": 360,
"md5": "7e17dbd8923848ee821f1ec62c05ec1c",
"source": "Gracenote",
"category": null
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s32356_h3_ba.png",
"height": 270,
"width": 360,
"md5": "ea243af96f9655813daafb1b2644ea09",
"source": "Gracenote",
"category": null
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s44023_dark_360w_270h.png",
"height": 270,
"width": 360,
"md5": "68b1e1fed1df883923bd17fbd269989a",
"source": "Gracenote",
"category": "dark"
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s44023_gray_360w_270h.png",
"height": 270,
"width": 360,
"md5": "6ec63d29578be63686aa038f9d479a87",
"source": "Gracenote",
"category": "gray"
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s44023_light_360w_270h.png",
"height": 270,
"width": 360,
"md5": "69a49c4a2184612888a1c3571afc2182",
"source": "Gracenote",
"category": "light"
}, {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s44023_white_360w_270h.png",
"height": 270,
"width": 360,
"md5": "e0de1cb788933169d888e24380471099",
"source": "Gracenote",
"category": "white"
}],
"logo": {
"URL": "https:\/\/schedulesdirect-api20141201.s3.us-east-1.amazonaws.com\/assets\/stationLogos\/s32356_h3_aa.png",
"height": 270,
"width": 360,
"md5": "7e17dbd8923848ee821f1ec62c05ec1c"
}
}
The final piece of information is metadata:
"metadata": {
"lineup": "USA-OTA-90210",
"modified": "2015-03-12T18:57:06Z",
"transport": "Antenna"
}
Metadata for a QAM lineup has the "modulation" field to differentiate it from a "Cable" lineup:
"metadata": {
"lineup": "USA-IA14438-QAM",
"modified": "2015-08-12T17:32:12Z",
"transport": "Cable",
"modulation": "QAM"
}
NOTE: Your code must not assume that the "map" section is first in the data, or that the "metadata" is last.
Automapping may be possible in some situations, but is user-driven. The automapping function accepts the "lineup.json" output from Silicon Dust's HDHomerun devices. It then runs a comparison against our database and returns potential lineup matches.
POST https://json.schedulesdirect.org/20141201/map/lineup/
Token: Required
The body of the request will be the output of:
GET http://ipAddressOfHDHR/lineup.json
If your grabber receives a 404, then the HDHomerun either doesn't support the call, (because it is too old), or the firmware isn't new enough.
If we have a match, the response will be something like:
{"USA-OTA-02116":100}
Indicating a 100% match. Matches above 90% are sent back as candidates.
If there are no match candidates, once your user has gone through the process of manually selecting a lineup by choosing their country, postal code and provider, you're encouraged to submit the lineup.json map with the now-known lineup to our database:
POST https://json.schedulesdirect.org/20141201/map/lineup/USA-OTA-02116
Token: Required
The body of the request will be the output of:
GET http://ipAddressOfHDHR/lineup.json
This may make it easier for the next user that's in the same area as the submitter, because now the database will have a match candidate for them.
POST https://json.schedulesdirect.org/20141201/programs
Token: Required
The body of the request will have the programIDs you are requesting.
Your client must send an Accept-Encoding that has "deflate,gzip" in it, even though the response will be gzip'ed. This is due to an implementation bug in 20140530 which will be fixed in 20141201.
NOTE: No more than 5000 programIDs in a single request.
["EP012801050074", "EP000000510142"]
The response will look like:
[
{"programID":"EP012801050074","resourceID":"8130493","titles":[{"title120":"Blue Bloods","titleLanguage":"en"}],"descriptions":{"description1000":[{"descriptionLanguage":"en","description":"The community and the mayor scrutinize Frank's department when an officer is accused of using excessive force; a Wall Street executive who was deeply in debt is murdered."}],"description100":[{"descriptionLanguage":"en","description":"An officer is accused of using excessive force; a Wall Street executive is murdered."}]},"originalAirDate":"2013-11-08","showType":"Series","entityType":"Episode","country":["USA"],"genres":["Crime drama"],"cast":[{"billingOrder":"01","role":"Actor","name":"Tom Selleck","characterName":"Frank Reagan","nameId":"63116","personId":"63116"},{"billingOrder":"02","role":"Actor","name":"Donnie Wahlberg","characterName":"Danny Reagan","nameId":"1862","personId":"1862"},{"billingOrder":"03","role":"Actor","name":"Bridget Moynahan","characterName":"Erin Reagan","nameId":"183686","personId":"182126"},{"billingOrder":"04","role":"Actor","name":"Will Estes","characterName":"Jamie Reagan","nameId":"201862","personId":"157064"},{"billingOrder":"05","role":"Actor","name":"Len Cariou","characterName":"Henry Reagan","nameId":"155923","personId":"155736"},{"billingOrder":"06","role":"Actor","name":"Amy Carlson","characterName":"Linda Reagan","nameId":"67576","personId":"67576"},{"billingOrder":"07","role":"Actor","name":"Sami Gayle","characterName":"Nicky Reagan-Boyle","nameId":"616491","personId":"592131"},{"billingOrder":"08","role":"Actor","name":"Marisa Ramirez","characterName":"Detective Maria Baez","nameId":"255200","personId":"251644"},{"billingOrder":"09","role":"Guest Star","name":"Gregory Jbara","characterName":"Garrett Moore","nameId":"209353","personId":"207365"},{"billingOrder":"10","role":"Guest Star","name":"Vanessa Ray","characterName":"Officer Eddie Janko","nameId":"589925","personId":"565651"},{"billingOrder":"11","role":"Guest Star","name":"Frank Whaley","characterName":"Gary Heller","nameId":"21925","personId":"21925"},{"billingOrder":"12","role":"Guest Star","name":"Haaz Sleiman","characterName":"Teri Damiri","nameId":"517936","personId":"503649"},{"billingOrder":"13","role":"Guest Star","name":"Aida Turturro","characterName":"Miss Dominga","nameId":"2515","personId":"2515"},{"billingOrder":"14","role":"Guest Star","name":"John Ventimiglia","characterName":"Dino Arbogast","nameId":"77477","personId":"77477"},{"billingOrder":"15","role":"Guest Star","name":"Matthew Humphreys","characterName":"Arthur Phillips","nameId":"509980","personId":"495985"},{"billingOrder":"16","role":"Guest Star","name":"Bruce Cutler","characterName":"Himself","nameId":"458395","personId":"449520"},{"billingOrder":"17","role":"Guest Star","name":"Kevin O'Rourke","nameId":"231971","personId":"228875"},{"billingOrder":"18","role":"Guest Star","name":"Elliot Villar","nameId":"533890","personId":"517145"},{"billingOrder":"19","role":"Guest Star","name":"Ali Ahn","nameId":"590409","personId":"566120"},{"billingOrder":"20","role":"Guest Star","name":"Tony Terraciano","nameId":"614369","personId":"589886"},{"billingOrder":"21","role":"Guest Star","name":"Andrew Terraciano","nameId":"614370","personId":"589887"},{"billingOrder":"22","role":"Guest Star","name":"Abigail Hawk","nameId":"614371","personId":"589888"},{"billingOrder":"23","role":"Guest Star","name":"Christian Keiber","nameId":"293187","personId":"289384"},{"billingOrder":"24","role":"Guest Star","name":"David Ramsey","nameId":"151252","personId":"151180"},{"billingOrder":"25","role":"Guest Star","name":"JJ Wynder"},{"billingOrder":"26","role":"Guest Star","name":"Gameela Wright"},{"billingOrder":"27","role":"Guest Star","name":"Gianmarco Soresi"},{"billingOrder":"28","role":"Guest Star","name":"Daniel Morgan Shelley"},{"billingOrder":"29","role":"Guest Star","name":"Arron Lloyd"},{"billingOrder":"30","role":"Guest Star","name":"Eric Arriola"},{"billingOrder":"31","role":"Guest Star","name":"Soraya Butler"},{"billingOrder":"32","role":"Guest Star","name":"Paul Douglas Anderson"},{"billingOrder":"33","role":"Guest Star","name":"Matt Raimo"}],"crew":[{"billingOrder":"01","role":"Executive Producer","name":"Leonard Goldberg","nameId":"379033","personId":"370158"},{"billingOrder":"02","role":"Executive Producer","name":"Kevin Wade","nameId":"268274","personId":"264698"},{"billingOrder":"03","role":"Writer","name":"Ian Biederman"},{"billingOrder":"04","role":"Director","name":"Ralph Hemecker","nameId":"175212","personId":"173730"}],"contentRating":[{"body":"USA Parental Rating","code":"TV14","country":"USA","contentWarning":["L","V"],"contentAdvisory":["Language","Violence"]},{"body":"Departamento de Justi\u00e7a, Classifica\u00e7\u00e3o, T\u00edtulos e Qualifica\u00e7\u00e3o","code":"14","country":"BRA"},{"body":"Freiwillige Selbstkontrolle Fernsehen","code":"16","country":"DEU"},{"body":"Australian Classification Board","code":"M","country":"AUS"},{"body":"Film & Publication Board","code":"16","country":"ZAF"},{"body":"Canadian Parental Rating","code":"14+","country":"CAN"},{"body":"Mediakasvatus- ja kuvaohjelmayksikk\u00f6","code":"K12","country":"FIN"},{"body":"Arcom","code":"-10","country":"FRA"},{"body":"R\u00e9gie du cin\u00e9ma","code":"13+","country":"CAN"},{"body":"UK Content Provider","code":"PG","country":"GBR"},{"body":"Freiwillige Selbstkontrolle der Filmwirtschaft","code":"12","country":"FIN"},{"body":"Direcci\u00f3n General de Radio, Televisi\u00f3n y Cinematograf\u00eda","code":"B","country":"MEX"},{"body":"Kijkwijzer","code":"12","country":"NLD","contentWarning":["Coarse Language","Fear","Violence"]}],"episodeTitle150":"Drawing Dead","metadata":[{"TVmaze":{"season":4,"episode":7,"url":"https:\/\/www.tvmaze.com\/episodes\/6778\/blue-bloods-4x07-drawing-dead"}},{"Gracenote":{"season":4,"episode":7}}],"duration":2640,"hasImageArtwork":true,"hasEpisodeArtwork":true,"hasSeasonArtwork":true,"hasSeriesArtwork":true,"hash":"bed512e6ad2d1057ee05099284295c51","md5":"vtUS5q0tEFfuBQmShClcUQ"},
{"programID":"EP000000510142","titles":[{"title120":"A Different World"}],"eventDetails":{"subType":"Series"},"descriptions":{"description1000":[{"descriptionLanguage":"en","description":"Whitley and Dwayne tell new students about their honeymoon in Los Angeles."}]},"originalAirDate":"1992-09-24","genres":["Sitcom"],"episodeTitle150":"Honeymoon in L.A.","metadata":[{"Gracenote":{"season":6,"episode":1}}],"cast":[{"personId":"700","nameId":"700","name":"Jasmine Guy","role":"Actor","billingOrder":"01"},{"personId":"729","nameId":"729","name":"Kadeem Hardison","role":"Actor","billingOrder":"02"},{"personId":"120","nameId":"120","name":"Darryl M. Bell","role":"Actor","billingOrder":"03"},{"personId":"1729","nameId":"1729","name":"Cree Summer","role":"Actor","billingOrder":"04"},{"personId":"217","nameId":"217","name":"Charnele Brown","role":"Actor","billingOrder":"05"},{"personId":"1811","nameId":"1811","name":"Glynn Turman","role":"Actor","billingOrder":"06"},{"personId":"1232","nameId":"1232","name":"Lou Myers","role":"Actor","billingOrder":"07"},{"personId":"1363","nameId":"1363","name":"Jada Pinkett","role":"Guest Star","billingOrder":"08"},{"personId":"222967","nameId":"225536","name":"Ajai Sanders","role":"Guest Star","billingOrder":"09"},{"personId":"181744","nameId":"183292","name":"Karen Malina White","role":"Guest Star","billingOrder":"10"},{"personId":"305017","nameId":"318897","name":"Patrick Y. Malone","role":"Guest Star","billingOrder":"11"},{"personId":"9841","nameId":"9841","name":"Bumper Robinson","role":"Guest Star","billingOrder":"12"},{"personId":"426422","nameId":"435297","name":"Sister Souljah","role":"Guest Star","billingOrder":"13"},{"personId":"25","nameId":"25","name":"Debbie Allen","role":"Guest Star","billingOrder":"14"},{"personId":"668","nameId":"668","name":"Gilbert Gottfried","role":"Guest Star","billingOrder":"15"}],"showType":"Series","hasImageArtwork":true,"md5":"P5kz0QmCeYxIA+yL0H4DWw"}
]
Taking the first response and feeding it into pro.jsonlint.com:
{
"programID": "EP012801050074",
"resourceID": "8130493",
"titles": [
{
"title120": "Blue Bloods",
"titleLanguage": "en"
}
],
"descriptions": {
"description1000": [
{
"descriptionLanguage": "en",
"description": "The community and the mayor scrutinize Frank's department when an officer is accused of using excessive force; a Wall Street executive who was deeply in debt is murdered."
}
],
"description100": [
{
"descriptionLanguage": "en",
"description": "An officer is accused of using excessive force; a Wall Street executive is murdered."
}
]
},
"originalAirDate": "2013-11-08",
"showType": "Series",
"entityType": "Episode",
"country": [
"USA"
],
"genres": [
"Crime drama"
],
"cast": [
{
"billingOrder": "01",
"role": "Actor",
"name": "Tom Selleck",
"characterName": "Frank Reagan",
"nameId": "63116",
"personId": "63116"
},
{
"billingOrder": "02",
"role": "Actor",
"name": "Donnie Wahlberg",
"characterName": "Danny Reagan",
"nameId": "1862",
"personId": "1862"
},
{
"billingOrder": "03",
"role": "Actor",
"name": "Bridget Moynahan",
"characterName": "Erin Reagan",
"nameId": "183686",
"personId": "182126"
},
{
"billingOrder": "04",
"role": "Actor",
"name": "Will Estes",
"characterName": "Jamie Reagan",
"nameId": "201862",
"personId": "157064"
},
{
"billingOrder": "05",
"role": "Actor",
"name": "Len Cariou",
"characterName": "Henry Reagan",
"nameId": "155923",
"personId": "155736"
},
{
"billingOrder": "06",
"role": "Actor",
"name": "Amy Carlson",
"characterName": "Linda Reagan",
"nameId": "67576",
"personId": "67576"
},
{
"billingOrder": "07",
"role": "Actor",
"name": "Sami Gayle",
"characterName": "Nicky Reagan-Boyle",
"nameId": "616491",
"personId": "592131"
},
{
"billingOrder": "08",
"role": "Actor",
"name": "Marisa Ramirez",
"characterName": "Detective Maria Baez",
"nameId": "255200",
"personId": "251644"
},
{
"billingOrder": "09",
"role": "Guest Star",
"name": "Gregory Jbara",
"characterName": "Garrett Moore",
"nameId": "209353",
"personId": "207365"
},
{
"billingOrder": "10",
"role": "Guest Star",
"name": "Vanessa Ray",
"characterName": "Officer Eddie Janko",
"nameId": "589925",
"personId": "565651"
},
{
"billingOrder": "11",
"role": "Guest Star",
"name": "Frank Whaley",
"characterName": "Gary Heller",
"nameId": "21925",
"personId": "21925"
},
{
"billingOrder": "12",
"role": "Guest Star",
"name": "Haaz Sleiman",
"characterName": "Teri Damiri",
"nameId": "517936",
"personId": "503649"
},
{
"billingOrder": "13",
"role": "Guest Star",
"name": "Aida Turturro",
"characterName": "Miss Dominga",
"nameId": "2515",
"personId": "2515"
},
{
"billingOrder": "14",
"role": "Guest Star",
"name": "John Ventimiglia",
"characterName": "Dino Arbogast",
"nameId": "77477",
"personId": "77477"
},
{
"billingOrder": "15",
"role": "Guest Star",
"name": "Matthew Humphreys",
"characterName": "Arthur Phillips",
"nameId": "509980",
"personId": "495985"
},
{
"billingOrder": "16",
"role": "Guest Star",
"name": "Bruce Cutler",
"characterName": "Himself",
"nameId": "458395",
"personId": "449520"
},
{
"billingOrder": "17",
"role": "Guest Star",
"name": "Kevin O'Rourke",
"nameId": "231971",
"personId": "228875"
},
{
"billingOrder": "18",
"role": "Guest Star",
"name": "Elliot Villar",
"nameId": "533890",
"personId": "517145"
},
{
"billingOrder": "19",
"role": "Guest Star",
"name": "Ali Ahn",
"nameId": "590409",
"personId": "566120"
},
{
"billingOrder": "20",
"role": "Guest Star",
"name": "Tony Terraciano",
"nameId": "614369",
"personId": "589886"
},
{
"billingOrder": "21",
"role": "Guest Star",
"name": "Andrew Terraciano",
"nameId": "614370",
"personId": "589887"
},
{
"billingOrder": "22",
"role": "Guest Star",
"name": "Abigail Hawk",
"nameId": "614371",
"personId": "589888"
},
{
"billingOrder": "23",
"role": "Guest Star",
"name": "Christian Keiber",
"nameId": "293187",
"personId": "289384"
},
{
"billingOrder": "24",
"role": "Guest Star",
"name": "David Ramsey",
"nameId": "151252",
"personId": "151180"
},
{
"billingOrder": "25",
"role": "Guest Star",
"name": "JJ Wynder"
},
{
"billingOrder": "26",
"role": "Guest Star",
"name": "Gameela Wright"
},
{
"billingOrder": "27",
"role": "Guest Star",
"name": "Gianmarco Soresi"
},
{
"billingOrder": "28",
"role": "Guest Star",
"name": "Daniel Morgan Shelley"
},
{
"billingOrder": "29",
"role": "Guest Star",
"name": "Arron Lloyd"
},
{
"billingOrder": "30",
"role": "Guest Star",
"name": "Eric Arriola"
},
{
"billingOrder": "31",
"role": "Guest Star",
"name": "Soraya Butler"
},
{
"billingOrder": "32",
"role": "Guest Star",
"name": "Paul Douglas Anderson"
},
{
"billingOrder": "33",
"role": "Guest Star",
"name": "Matt Raimo"
}
],
"crew": [
{
"billingOrder": "01",
"role": "Executive Producer",
"name": "Leonard Goldberg",
"nameId": "379033",
"personId": "370158"
},
{
"billingOrder": "02",
"role": "Executive Producer",
"name": "Kevin Wade",
"nameId": "268274",
"personId": "264698"
},
{
"billingOrder": "03",
"role": "Writer",
"name": "Ian Biederman"
},
{
"billingOrder": "04",
"role": "Director",
"name": "Ralph Hemecker",
"nameId": "175212",
"personId": "173730"
}
],
"contentRating": [
{
"body": "USA Parental Rating",
"code": "TV14",
"country": "USA",
"contentWarning": [
"L",
"V"
],
"contentAdvisory": [
"Language",
"Violence"
]
},
{
"body": "Departamento de Justiça, Classificação, Títulos e Qualificação",
"code": "14",
"country": "BRA"
},
{
"body": "Freiwillige Selbstkontrolle Fernsehen",
"code": "16",
"country": "DEU"
},
{
"body": "Australian Classification Board",
"code": "M",
"country": "AUS"
},
{
"body": "Film & Publication Board",
"code": "16",
"country": "ZAF"
},
{
"body": "Canadian Parental Rating",
"code": "14+",
"country": "CAN"
},
{
"body": "Mediakasvatus- ja kuvaohjelmayksikkö",
"code": "K12",
"country": "FIN"
},
{
"body": "Arcom",
"code": "-10",
"country": "FRA"
},
{
"body": "Régie du cinéma",
"code": "13+",
"country": "CAN"
},
{
"body": "UK Content Provider",
"code": "PG",
"country": "GBR"
},
{
"body": "Freiwillige Selbstkontrolle der Filmwirtschaft",
"code": "12",
"country": "FIN"
},
{
"body": "Dirección General de Radio, Televisión y Cinematografía",
"code": "B",
"country": "MEX"
},
{
"body": "Kijkwijzer",
"code": "12",
"country": "NLD",
"contentWarning": [
"Coarse Language",
"Fear",
"Violence"
]
}
],
"episodeTitle150": "Drawing Dead",
"metadata": [
{
"TVmaze": {
"season": 4,
"episode": 7,
"url": "https://www.tvmaze.com/episodes/6778/blue-bloods-4x07-drawing-dead"
}
},
{
"Gracenote": {
"season": 4,
"episode": 7
}
}
],
"duration": 2640,
"hasImageArtwork": true,
"hasEpisodeArtwork": true,
"hasSeasonArtwork": true,
"hasSeriesArtwork": true,
"hash": "bed512e6ad2d1057ee05099284295c51",
"md5": "vtUS5q0tEFfuBQmShClcUQ"
}
NOTE: Certain elements in the response are "arrays"; in the "metadata" element you can see that we offer Gracenote and TVMaze Season / Episode information.
There are two potential error conditions your code may receive as a response; one is temporary and one is permanent. In the following instance the same programID was requested:
{
"programID": "EP000000060003",
"code": 6001,
"message": "The programID you requested has been queued for generation but is not yet ready for download. Retry."
}
In this case the programID you requested is valid, but isn't available at the server at the moment and is being generated. Code 6001 indicates a soft failure.
A code 6000 error indicates a permanent failure; if the programID was found in the schedule and you receive a code 6000 error when trying to retrieve it then send email to grabber@schedulesdirect.org.
Your client should maintain a cached copy of the program data; if the MD5 for a programID differs then your client will know that it should re-download the program data.
See Program Response for details on the fields.
See Retrieving Images for information on how your client can retrieve images.
You may want to obtain the generic description of a program; this is only available for "EP" types.
POST https://json.schedulesdirect.org/20141201/metadata/description/
Token: Required
The body of the request must contain the programIDs:
["EP000000060011","EP000186930001"]
Will return:
{
"SH000000060000": {
"code": 0,
"description100": "A cafe owner attempts to repatriate
escapees during World War II.",
"description1000": "A French cafe owner tries to ride out
World War II. Caught between the Gestapo and the Resistance and forced
into working with both, René also struggles to hide evidence of his
affairs with the waitresses from his wife, who, though she can't carry
a tune, frequently performs as a singer in the cafe."
},
"SH000186930000": {
"code": 0,
"description100": "Homer and Marge Simpson raise Bart, Lisa
and baby Maggie.",
"description1000": "This long-running animated comedy focuses
on the eponymous family in the town of Springfield in an unnamed U.S.
state. The head of the Simpson family, Homer, is not a typical family
man. A nuclear-plant employee, he does his best to lead his family but
often finds that they are leading him. The family includes loving,
blue-haired matriarch Marge, troublemaking son Bart, overachieving
daughter Lisa and baby Maggie. Other Springfield residents include the
family's religious neighbor, Ned Flanders, family physician Dr.
Hibbert, Moe the bartender and police chief Clancy Wiggum."
}
}
The "code" in each response has the following meaning:
- 0 - no error.
- 6000 - Invalid programID, don't try again.
- 6001 - ProgramID is valid but wasn't available on the server. Try again in a few minutes.
You may have up to 500 programIDs in the request.
Your code should send unique requests; sending the same programID multiple times, or incrementing the programID by one episode will always return the same generic description.
If you have a need to obtain the programID of a particular program in another language, you may use the cross-reference endpoint:
POST https://json.schedulesdirect.org/20141201/xref
Token: required
Body of request:
["EP000000060013","EP006883590001","EP000000060013"]
NOTE: the above request has a deliberate duplicate; the response shows that duplicates are eliminated.
Response:
{
"EP000000060013": [
{
"programID": "EP000000060013",
"md5": "6vW1nF3FuR776arDSH0XTg",
"titleLanguage": "en-GB",
"descriptionLanguage": "en",
"titleLanguageName": "English - United Kingdom",
"descriptionLanguageName": "English"
},
{
"programID": "EP012692210042",
"md5": "8wnsdTiBNWTF9CAYVRPmqg",
"titleLanguage": "en-GB",
"descriptionLanguage": "en-GB",
"titleLanguageName": "English - United Kingdom",
"descriptionLanguageName": "English - United Kingdom"
}
],
"EP006883590001": [
{
"programID": "EP006883590001",
"md5": "XyiEHwIyEUZYPsTN+aZfvA",
"titleLanguage": "en",
"descriptionLanguage": "en",
"titleLanguageName": "English",
"descriptionLanguageName": "English"
},
{
"programID": "EP009143120237",
"md5": "CsPQ0uMyq94ziPycW5w/vg",
"titleLanguage": "fr-CA",
"descriptionLanguage": "fr-CA",
"titleLanguageName": "French - Canada",
"descriptionLanguageName": "French - Canada"
},
{
"programID": "EP012602100088",
"md5": "EQElSe2dh94c1Wgg6uR4kA",
"titleLanguage": "en",
"descriptionLanguage": "en-GB",
"titleLanguageName": "English",
"descriptionLanguageName": "English - United Kingdom"
},
{
"programID": "EP016178050088",
"md5": "obYTp2AhR+pL1wnvVNgjTQ",
"titleLanguage": "en",
"descriptionLanguage": "sv",
"titleLanguageName": "English",
"descriptionLanguageName": "Swedish"
},
{
"programID": "EP018574310086",
"md5": "Sm5NoYgBIPa0YEyQQYepRQ",
"titleLanguage": "fr-CA",
"descriptionLanguage": "de",
"titleLanguageName": "French - Canada",
"descriptionLanguageName": "German"
},
{
"programID": "EP018809220039",
"md5": "EBc327AXoq39I51H2AYBUA",
"titleLanguage": "it",
"descriptionLanguage": "it",
"titleLanguageName": "Italian",
"descriptionLanguageName": "Italian"
},
{
"programID": "EP019377030109",
"md5": "Wj96H9INNQgf0dBl0Tg40Q",
"titleLanguage": "fr-CA",
"descriptionLanguage": "fr",
"titleLanguageName": "French - Canada",
"descriptionLanguageName": "French"
},
{
"programID": "EP019817400001",
"md5": "BSbHR+Hdw8iv/v6GKeqc2Q",
"titleLanguage": "en",
"descriptionLanguage": "fi",
"titleLanguageName": "English",
"descriptionLanguageName": "Finnish"
},
{
"programID": "EP020127870069",
"md5": "S2aRJomclq9BbUXxG5sUPA",
"titleLanguage": "en",
"descriptionLanguage": "no",
"titleLanguageName": "English",
"descriptionLanguageName": "Norwegian"
},
{
"programID": "EP020436570027",
"md5": "vsNGFSimMYZzBHDmOlKoBw",
"titleLanguage": "en",
"descriptionLanguage": "es-ES",
"titleLanguageName": "English",
"descriptionLanguageName": "Spanish - Spain"
}
]
}
Your application can then request the programID that the user is interested in.
POST https://json.schedulesdirect.org/20141201/schedules
Token: Required
The body of the request must contain stationID elements. If the "date" element isn't included, you will be sent the schedule for "today" through the last day of schedule data on the server.
NOTE: If your code is going to request specific dates, then it should first make the call to Download the MD5 and lastModified for stationIDs This will let your code know what the MD5 is for a schedule for each day that we have data on the server, and will also give you the valid range of dates. If your code is caching the MD5 for each stationID / day combination, it will know whether it has to re-download a schedule.
NOTE: No more than 5000 stationIDs in a single request.
NOTE: The dates are not a range; you must include each date individually.
[
{
"stationID": "20454",
"date": [
"2015-03-13",
"2015-03-17"
]
},
{
"stationID": "10021",
"date": [
"2015-03-12",
"2015-03-13"
]
}
]
The response will be an array of elements. Each stationID / date combination will contain a metadata element that provides an MD5 value which should be stored so that your code can determine if the schedule for a stationID / date combination needs to be refreshed.
[
{
"stationID": "20454",
"programs": [
{
"programID": "SH005371070000",
"airDateTime": "2015-03-03T00:00:00Z",
"duration": 1800,
"md5": "Sy8HEMBPcuiAx3FBukUhKQ",
"new": true,
"audioProperties": [
"stereo",
"cc"
],
"videoProperties": [
"hdtv"
]
},
{
"programID": "EP000014577244",
"airDateTime": "2015-03-03T00:30:00Z",
"duration": 1800,
"md5": "25DNXVXO192JI7Y9vSW9lQ",
"new": true,
"audioProperties": [
"stereo",
"cc"
],
"videoProperties": [
"hdtv"
]
},
(etc for the remaining schedules for this stationID / date combination.)
{
"programID": "EP014145320829",
"airDateTime": "2015-03-03T23:30:00Z",
"duration": 1800,
"md5": "A6RCPnx4SjKN3oaZtXxNfw",
"new": true,
"audioProperties": [
"stereo",
"cc"
],
"videoProperties": [
"hdtv"
]
}
],
"metadata": {
"modified": "2015-03-02T15:56:02Z",
"md5": "UtL+hq0sqtCTZVFrGHZ5sg",
"startDate": "2015-03-03"
}
},
{
"stationID": "20454",
"programs": [
{
"programID": "SH005371070000",
"airDateTime": "2015-03-04T00:00:00Z",
"duration": 1800,
"md5": "Sy8HEMBPcuiAx3FBukUhKQ",
"new": true,
"audioProperties": [
"stereo",
"cc"
],
"videoProperties": [
"hdtv"
]
},
(more schedule elements)
{
"programID": "EP014145320830",
"airDateTime": "2015-03-04T23:30:00Z",
"duration": 1800,
"md5": "LdPQVqsQJWTcX1b5k2VPGQ",
"new": true,
"audioProperties": [
"stereo",
"cc"
],
"videoProperties": [
"hdtv"
]
}
],
"metadata": {
"modified": "2015-03-02T15:56:02Z",
"md5": "ZZPts55w9WUP1rMRvKsGDw",
"startDate": "2015-03-04"
}
},
{
"stationID": "10021",
"programs": [
{
"programID": "EP018632100004",
"airDateTime": "2015-03-03T01:56:00Z",
"duration": 3840,
"md5": "J+AOJ/ofAQdp12Bh3U+C+A",
"audioProperties": [
"cc"
],
"ratings": [
{
"body": "USA Parental Rating",
"code": "TV14"
}
]
},
Your program must be able to process UTF-8 characters.
stationID - max 12 characters. Mandatory. This is a string, and your code must not treat it as an integer. Provides information to the grabber regarding the stationID that this schedule is for.
programs - an array of program data. Mandatory. Must contain at least one element.
Each element of the programs array will contain:
programID - 14 characters. Mandatory. What programID will the data be for.
airDateTime - 20 characters. Mandatory. "2014-10-03T00:00:00Z". This will always be in "Z" time; your grabber must make any adjustments to localtime if it does not natively work in "Z" time internally.
duration - integer. Mandatory. Duration of the program in seconds.
md5 - 22 characters. Mandatory. The MD5 hash value of the JSON data on the server for the programID. If your application has cached the JSON for the program, but the cached MD5 isn't the same as what is in the schedule, that should trigger your grabber to refresh the JSON for the programID because it's changed.
The following program elements are booleans and are optional. If a boolean is not in the schedule, then assume "FALSE". If a boolean is in the schedule, do not assume "TRUE".
- new - is this showing new?
- cableInTheClassroom
- catchup - typically only found outside of North America
- continued - typically only found outside of North America
- educational
- joinedInProgress
- leftInProgress
- premiere - Should only be found in Miniseries and Movie program types.
- programBreak - Program stops and will restart later (frequently followed by a continued). Typically only found outside of North America.
- repeat - An encore presentation. Repeat should only be found on a second telecast of sporting events.
- signed - Program has an on-screen person providing sign-language translation.
- subjectToBlackout
- timeApproximate
- free - the program is on a channel which typically has a cost, such as pay-per-view, but in this instance is free.
The following are optional, but can be used to indicate additional information.
- liveTapeDelay - is this showing Live, or Tape Delayed?. Possible values: "Live", "Tape", "Delay".
- isPremiereOrFinale - Values are: "Season Premiere", "Season Finale", "Series Premiere", "Series Finale", "Premiere", "Finale"
- ratings - an array of ratings values.
- body: what classification body is providing the rating?
- code: what rating was assigned?
Example:
"ratings": [
{
"body": "USA Parental Rating",
"code": "TVPG"
}
]
Programs may be rated by various bodies, so your code should iterate through the bodies and use the one appropriate for your locale.
NOTE: In the next version of the API, the ratings element will be removed
from the schedule entity; there is a "contentRating" field associated with
the program which should be used instead.
NOTE: Previous versions of this documentation indicated that the ratings element would be removed; this is no longer the case. The rating element in the schedule will remain, in order to allow for a content provider to have a special version of a program. For example, a movie may have a "TV edit", which removes objectionable content, so the rating in the schedule would reflect the ratings for the edited program, while the rating body within the program would reflect the original rating.
- multipart - indicates whether the program is one of a series.
"multipart": {
"partNumber": 1,
"totalParts": 3
}
audioProperties - optional. An array of audio properties.
- Atmos - Dolby Atmos
- cc - Closed Captioned
- DD
- DD 5.1
- Dolby
- dubbed
- dvs - Descriptive Video Service
- SAP - Secondary Audio Program
- stereo
- subtitled
- surround
videoProperties - optional. An array of video properties.
- 3d - is this showing in 3d
- enhanced - Enhanced is better video quality than Standard Definition, but not true High Definition. (720p / 1080i)
- hdtv - the content is in High Definition
- hdr - the content has High Dynamic Range. All HDR content is UHDTV, but not all UHDTV content has HDR
- letterbox
- sdtv
- uhdtv - the content is in "UHDTV"; this is provider-dependent and does not imply any particular resolution or encoding
The following metadata is associated with the schedule (it is not inside the programs array)
- modified - 20 characters. Mandatory. Follows strftime() format; "Y-m-d\TH:i:s\Z" The timestamp for the creation time of this schedule on the server.
- md5 - 22 characters. Mandatory. What is the MD5 for this schedule (stationID and programs elements) - metadata is not included in the MD5 calculation.
- startDate - the start date of the JSON schedule. Mandatory. strftime() "Y-m-d" format.
- code - optional. Indicates if there were errors with the station. It is possible that your client has requested a stationID which has been deleted upstream, but that your client still believes is "live" because it hasn't updated the lineup.
You may receive the following as a response element:
[
{
"stationID": "10489",
"serverID": "20141201.web.1",
"code": 2201,
"response": "STATIONID_DELETED",
"programs": [],
"metadata": {
"code": 2201,
"modified": "1970-01-01",
"md5": "CAFEDEADBEEFCAFEDEADBE",
"isDeleted": true
}
}
]
This occurs if the lineup has not yet been updated to reflect that a stationID has been deleted, so requesting data for the stationID will result in an error. This may also occur if the lineup has been updated on the server side, but the client hasn't downloaded an updated lineup map.
{
"response": "SCHEDULE_QUEUED",
"code": 7100,
"serverID": "20141201.1",
"message": "The schedule you requested has been queued for generation but is not yet ready for download. Retry.",
"datetime": "2014-12-04T20:38:15Z",
"stationID": "50475",
"retryTime": "2014-12-04T20:48:15Z"
}
The server creates schedules just-in-time based on user requests and channels which are active. If you receive the above response, your code should honor the "retryTime" parameter and wait at least this long before retrying to download the schedule. This will give the backend system enough time to generate the schedule for you.
[
{
"stationID": "92371",
"serverID": "20141201.web.1",
"code": 7020,
"response": "SCHEDULE_RANGE_EXCEEDED",
"minDate": "2015-06-21",
"maxDate": "2015-07-12",
"requestedDate": "2015-07-20",
"message": "Date requested (2015-07-20) not within 2015-06-21 -> 2015-07-12 for stationID 92371."
}
]
Error 7020 occurs when the requested date is out of range of what's on the server. If your code uses the MD5 function as decribed in the next section it will know what the min / max dates are prior to requesting the schedule.
POST https://json.schedulesdirect.org/20141201/schedules/md5
Token: Required
The body of the request will have the stationIDs that you are requesting, with an optional "date" element to request specific dates for this stationID. If you do not include a "date" element the server will send the MD5 for "today" through the furthest date we have information for.
This function is useful to determine whether a particular stationID has an updated schedule; schedules are typically updated 4 times per day, 7 days per week. If a schedule has been updated, the MD5 and lastModified for that stationID for that date will be updated. Using this function, your client can determine (through use of a local cache) if it needs to download a new schedule.
NOTE: No more than 5000 stationIDs in a single request.
NOTE: The dates are not a range; you must include each date individually.
[
{
"stationID": "10021"
},
{
"stationID": "31590",
"date": [
"2015-03-12",
"2015-03-17"
]
}
]
Days more than one day in the past (referencing to midnight, Zulu time) are invalid.
The response will look like this:
{
"10021": {
"2015-03-02": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "90OhzuWDRZ/3pDA8kiD/3Q"
},
"2015-03-03": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "SpVOfFY4a8gQrrZjOqyK8g"
},
"2015-03-04": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "M28yUIqJyWKYK678cXf0yg"
},
"2015-03-05": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "va+LAHqHRthUCIvHyYWvmQ"
},
"2015-03-06": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "Vh+/n50xOs9beZwYttNmkg"
},
"2015-03-07": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "Zkwk4WR/OdZRJW7VxFmpIg"
},
"2015-03-08": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "E71/Hhn7g9hjm9C62ZRu/w"
},
"2015-03-09": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:58Z",
"md5": "57bRSvsGzlcOABs6L4+rJg"
},
"2015-03-10": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "fSxdu0nSh9sjxSIeaxke9Q"
},
"2015-03-11": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "7RIUvb4lOYnH+sLR2AbZNw"
},
"2015-03-12": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "GtQa6tTyXbV766VIjtbPig"
},
"2015-03-13": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "loNYYtTiRSEGV4Go9MdwGQ"
},
"2015-03-14": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "60eiM0FxIIWHuEHIVrPTcQ"
},
"2015-03-15": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "scsW02JiUimh2c9tFJxcZA"
},
"2015-03-16": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "IW54d8U3T3NoP2qVXRqlNg"
},
"2015-03-17": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "oBn5rCpJHnL+VZ4IAzc1XQ"
},
"2015-03-18": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "E3Rg8FDt0U8skbUEtwFh2A"
},
"2015-03-19": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "K8oSxRaIgeNLc8SZetzwpQ"
},
"2015-03-20": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "CcK6uEz2WCkpLQnMP0Wl0w"
},
"2015-03-21": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "tmEF/TxAjJ1maNBx93nitA"
},
"2015-03-22": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "jShohWNfMZDiDp8DmrlroQ"
},
"2015-03-23": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:54:59Z",
"md5": "sFF9EE8hJYDzSgUZA0tycQ"
}
},
"31590": {
"2015-03-02": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:56:17Z",
"md5": "cuq9QUJZRygLx21821qlUw"
},
"2015-03-03": {
"code": 0,
"message": "OK",
"lastModified": "2015-03-02T15:56:17Z",
"md5": "ZDPKmNdzvnCF5EzY855cLQ"
}
}
}
(etc for all stationIDs requested)
DELETE /messages/{messageID}
Deletes non-system status messages from the status response.
Schedules Direct can provide information about sporting events which may be used by an application to extend the recording of a program which is running long due to a tie score or delay, or to stop a recording which the user has configured with a fixed over-run time.
As of 2015-11-28, we provide responses for: NFL, NHL, NBA and MLB.
NOTE: a sporting event which runs late will not cause a schedule re-generation, because we won't know if the broadcaster is going to shift the starting time for subsequent programs, or just "joined in progress".
NOTE: the "isComplete" flag indicates that the event is over; broadcasters may choose to have post-game analysis, so your client must take that into consideration.
The URL accepts a single programID that you're interested in.
GET https://json.schedulesdirect.org/20141201/metadata/stillRunning/{programID}
Token: Required
If you are requesting a valid program, but are the first client to request this programID, the response will be:
{
"response": "PROGRAMID_QUEUED",
"code": 6001,
"serverID": "20141201.web.2",
"message": "The programID you requested has been queued for generation but is not yet ready for download. Retry.",
"datetime": "2015-11-27T03:21:02Z",
"programID": "SP003190180000"
}
Your client should wait 30 seconds before retrying.
For a program which is still in progress, "isComplete" will be "false":
{
"code": 0,
"message": "OK",
"programID": "SP003190180000",
"response": "OK",
"isComplete": false,
"serverID": "Test1",
"datetime": "2015-11-27T02:48:40Z",
"result": {
"homeTeam": {
"name": "Green Bay",
"score": "10"
},
"awayTeam": {
"name": "Chicago",
"score": "7"
}
}
}
For a program which is over, "isComplete" will be "true":
{
"code": 0,
"message": "OK",
"programID": "SP003190160000",
"response": "OK",
"isComplete": true,
"serverID": "Test1",
"datetime": "2015-11-27T01:39:28Z",
"result": {
"homeTeam": {
"name": "Detroit",
"score": "45"
},
"awayTeam": {
"name": "Philadelphia",
"score": "14"
}
}
}
If you request a program which is valid, but is still in the future, you will get:
{
"response": "FUTURE_PROGRAM",
"code": 6002,
"serverID": "20141201.web.2",
"message": "The programID you requested has not occurred yet, so isComplete status is unknown.",
"datetime": "2015-11-27T03:08:57Z",
"programID": "SP003264810000",
"eventStartDateTime": "2015-11-29T20:00Z"
}
If you request an invalid program, or a sport which we do not track, you will receive:
{
"response": "INVALID_PROGRAMID",
"code": 6000,
"serverID": "20141201.web.2",
"message": "Could not find requested programID.",
"datetime": "2015-11-27T03:13:30Z"
}
Images, fanart, logos, etc will have a URI in the JSON response. If the URI is complete, it will point to Amazon S3, in which case your application should pull the image directly from Amazon. If the URI is incomplete (no http:// for example), then send the request to Schedules Direct. Your application will then receive a 303 redirect.
There is a number of metadata elements which are available to the client.
If the program contains a boolean called "hasImageArtwork" and it is TRUE, this means that this particular program has artwork available, such as DVD coverart, stills from the program, title cards, etc.
{
"programID": "EP003851900001",
"titles": [
{
"title120": "Gilmore Girls"
}
],
"descriptions": {
"description100": [
{
"descriptionLanguage": "en",
"description": "A woman (Lauren Graham) endeavors to raise a daughter (Alexis Bledel) on her own."
}
],
"description1000": [
{
"descriptionLanguage": "en",
"description": "Lorelai must ask her estranged parents for financial help when her daughter, Rory, is accepted into a prestigious prep school."
}
]
},
"originalAirDate": "2000-10-05",
"genres": [
"Drama",
"Comedy"
],
"episodeTitle150": "Pilot",
"metadata": [
{
"Gracenote": {
"season": 1,
"episode": 1
}
}
],
"contentRating": [
{
"body": "Departamento de Justiça, Classificação, Títulos e Qualificação",
"code": "L"
},
{
"body": "USA Parental Rating",
"code": "TVPG"
}
],
"cast": [
{
"billingOrder": "01",
"role": "Actor",
"nameId": "68293",
"personId": "68293",
"name": "Lauren Graham"
},
{
"billingOrder": "02",
"role": "Actor",
"nameId": "183495",
"personId": "181941",
"name": "Alexis Bledel"
},
<snip>
{
"billingOrder": "09",
"role": "Actor",
"nameId": "39938",
"personId": "39938",
"name": "Liz Torres"
}
],
"crew": [
{
"billingOrder": "01",
"role": "Executive Producer",
"nameId": "191244",
"personId": "189517",
"name": "Amy Sherman-Palladino"
},
{
"billingOrder": "02",
"role": "Executive Producer",
"nameId": "253033",
"personId": "249480",
"name": "Gavin Polone"
},
{
"billingOrder": "03",
"role": "Director",
"nameId": "78100",
"personId": "78100",
"name": "Lesli Linka Glatter"
},
{
"billingOrder": "04",
"role": "Writer",
"nameId": "191244",
"personId": "189517",
"name": "Amy Sherman-Palladino"
}
],
"showType": "Series",
"hasImageArtwork": true,
"md5": "hVdDQ1wTUCel5CY6BhLKqw"
}
The available image artwork index is retrieved by using the following URL:
POST https://json.schedulesdirect.org/20141201/metadata/programs/
Token: Required
The body of the message should contain the leftmost 10 characters of the programID:
["SH00712240", "EP00385190"]
Which will return an index of what content is available:
[
{
"programID": "SH00712240",
"data": [
{
"width": "135",
"height": "180",
"uri": "assets/p282288_b_v2_aa.jpg",
"size": "Sm",
"aspect": "3x4",
"category": "Banner-L3",
"text": "yes",
"primary": "true",
"tier": "Series"
},
{
"width": "720",
"height": "540",
"uri": "assets/p282288_b_h6_aa.jpg",
"size": "Lg",
"aspect": "4x3",
"category": "Banner-L3",
"text": "yes",
"primary": "true",
"tier": "Series"
},
{
"width": "960",
"height": "1440",
"uri": "assets/p282288_b_v8_aa.jpg",
"size": "Ms",
"aspect": "2x3",
"category": "Banner-L3",
"text": "yes",
"primary": "true",
"tier": "Series"
},
<snip>
{
"width": "180",
"height": "135",
"uri": "assets/p282288_b_h5_aa.jpg",
"size": "Sm",
"aspect": "4x3",
"category": "Banner-L3",
"text": "yes",
"primary": "true",
"tier": "Series"
}
]
},
{
"programID": "EP00385190",
"data": [
{
"width": "540",
"height": "720",
"caption": {
"content": "Alexis Bledel as Rory Gilmore",
"lang": "en"
},
"uri": "assets/p184655_n183495_cc_v4_aa.jpg",
"size": "Lg",
"aspect": "3x4",
"category": "Cast in Character",
"text": "no",
"primary": "true",
"tier": "Series"
},
<etc>
You may batch up to 500 elements in each request.
The returned JSON may contain a "rootId". If it does, you may obtain information using:
https://json.schedulesdirect.org/20141201/metadata/programs/{rootId}
GET https://json.schedulesdirect.org/20141201/metadata/programs/33125
Token: Required
Which returns:
[
{
"uri": "movies/AllPhotos/35605/35605_aa.jpg",
"height": "432",
"width": "288",
"primary": "true",
"category": "Poster Art",
"caption": {
"content": "Poster Art",
"lang": "en"
}
},
{
"uri": "movies/AllPhotos/35605/35605_aa_t.jpg",
"height": "108",
"width": "72",
"primary": "true",
"category": "Poster Art",
"caption": {
"content": "Poster Art",
"lang": "en"
}
},
{
"uri": "assets/35605_ab.jpg",
"height": "288",
"width": "432",
"category": "Scene Still",
"caption": {
"content": "Billy Bob Thornton and Tony Cox in Terry Zwigoff's BAD SANTA.",
"lang": "en"
}
},
<snip>
To retrieve a particular image, use the URI from the JSON index.
https://json.schedulesdirect.org/20141201/image/{uri}
Token: Required
So:
or
GET https://json.schedulesdirect.org/20141201/image/882a86de40012ed1b119084d73098130ab25ff29b144d1402a3c000e07cdf8bb.jpg (with the token provided in the request header)
This will send your client a 303 redirect which it must follow in order to retrieve the actual image:
NOTE: the redirect URL is valid for 120 seconds; do not cache it.
NOTE: If the URI is already "complete" and contains the S3 URL, then your client should access S3 directly. Notice the difference in the uri in the following example:
{
"width": "360",
"height": "270",
"uri": "assets/p10779614_l_h3_aa.jpg",
"size": "Md",
"aspect": "4x3",
"category": "Logo",
"text": "no",
"primary": "true",
"tier": "Series"
},
{
"width": "180",
"height": "135",
"uri": "https://s3.amazonaws.com/schedulesdirect/assets/p10779614_l_h5_aa.jpg",
"size": "Sm",
"aspect": "4x3",
"category": "Logo",
"text": "no",
"primary": "true",
"tier": "Series"
},
The program object also contains nameId and personId elements in the cast and crew section. The actor Lauren Graham has a nameId of 68293, so
GET https://json.schedulesdirect.org/20141201/metadata/celebrity/68293
Token: Required
Returns
[
{
"uri": "assets/35605_aq.jpg",
"height": "288",
"width": "432",
"category": "Scene Still",
"caption": {
"content": "Billy Bob Thornton and Lauren Graham in Terry Zwigoff's BAD SANTA.",
"lang": "en"
},
"rootId": "33125",
"title": "Bad Santa"
},
<snip>
}
Your grabber may use the same /image/ call with the URI to retrieve that image:
https://json.schedulesdirect.org/20141201/image/{uri}
https://json.schedulesdirect.org/20141201/image/assets/35605_aq.jpg
There are various fields in the JSON response.
- Banner – source-provided image, usually shows cast ensemble with source-provided text
- Banner-L1 - same as Banner
- Banner-L2 - source-provided image with plain text
- Banner-L3 - stock photo image with plain text
- Banner-LO - banner with Logo Only
- Banner-LOT - banner with Logo Only + Text indicating season number
- Iconic - representative series/season/episode image, no text
- Staple - the staple image is intended to cover programs which do not have a unique banner image.
- Cast Ensemble - cast ensemble, no text
- Cast in Character - individual cast member, no text
- Logo - official logo for program, sports organization, sports conference, or TV station
- Box Art - DVD box art, for movies only
- Poster Art – theatrical movie poster, standard sizes
- Scene Still – movie photos, legacy sizes
- Photo - same as Scene Still
- Photo-headshot - celebrity image
When retrieving an image, your application must confirm if it has received a JSON response and not a redirect.
{
"response": "TOKEN_MISSING",
"code": 1004,
"serverID": "20141201.web",
"message": "Token required but not provided in header or request URI.",
"datetime": "2025-01-31T23:08:12Z"
}
All image requests must have a token.
You may get:
{
"response": "MAX_IMAGE_DOWNLOADS",
"code": 5002,
"serverID": "20141201.debug",
"message": "Maximum image downloads reached. Counter resets every 24h. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6",
"datetime": "2025-01-31T23:17:17Z"
}
This code is used to indicate that an active subscriber has reached the maximum number of image downloads in a 24h period. Your application must stop making image requests, otherwise the user will be blocked. The 24h counter begins when the first image is downloaded.
There is also this possible response:
{
"response": "MAX_IMAGE_DOWNLOADS_TRIAL",
"code": 5003,
"serverID": "20141201.debug",
"message": "Maximum image downloads for trial user reached. Counter resets every 24h. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6",
"datetime": "2025-01-31T23:17:17Z"
}
This code indicates that this is a trial user for the SchedulesDirect JSON service, and they have downloaded the maximum number of images in a 24h period. Your application must stop making image requests, otherwise the user will be blocked.
There is also:
{
"response": "IMAGE_NOT_FOUND",
"code": 5000,
"serverID": "20141201.debug",
"message": "Could not find requested image. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6 if you are having issues.",
"datetime": "2025-02-11T03:11:59Z"
}
The URI which was presented doesn't exist, so your application must not make additional attempts to download this URI, otherwise the user will be blocked.
See API 20141201 Celebrity Metadata for details on how to obtain information for a celebrity.
The system may respond to a request and send back an error code.
Response | Internal Code | Error |
---|---|---|
0 | OK | OK |
1001 | INVALID_JSON | Unable to decode JSON |
1003 | USERAGENT_REQUIRED | Did not receive User-Agent in header. See https://github.com/SchedulesDirect/JSON-Service/wiki/API-20141201#tasks-your-client-must-perform |
1004 | TOKEN_MISSING | Token required but not provided in request header. |
1005 | UNKNOWN_CLIENT | Did not recognize the submitted client. |
1006 | MAX_CHUNK_EXCEEDED | The maximum number of elements in a single request is 5000. |
1007 | EMPTY_REQUEST | The request sent to the server was empty. |
1008 | INCORRECT_REQUEST | The request is improperly formatted. |
1009 | MAX_CHUNK_EXCEEDED | The maximum number of elements in a single request is 500. |
1010 | TOKEN_INVALID | Token is not 32 characters. |
2002 | REQUIRED_REQUEST_MISSING | Did not receive request. |
2004 | REQUIRED_PARAMETER_MISSING:COUNTRY | In order to search for lineups, you must supply a 3-letter country parameter. |
2005 | REQUIRED_PARAMETER_MISSING:POSTALCODE | In order to search for lineups, you must supply a postal code parameter. |
2020 | REQUIRED_PARAMETER_MISSING:PERSONID or NAMEID | Request is missing the personID / namedID in the path. |
2050 | INVALID_PARAMETER:COUNTRY | The COUNTRY parameter must be ISO-3166-1 alpha 3. See http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 |
2054 | INVALID_PARAMETER:UNKNOWN REQUEST | Your client may request available data for: COUNTRIES |
2055 | INVALID_PARAMETER:DEBUG | Unexpected debug connection from client. |
2100 | DUPLICATE_LINEUP | Lineup already in account. |
2101 | LINEUP_NOT_FOUND | Lineup not in account. Add lineup to account before requesting mapping. |
2102 | UNKNOWN_LINEUP | Invalid lineup requested. Check your COUNTRY / POSTALCODE combination for validity. |
2103 | INVALID_LINEUP_DELETE | Delete of lineup not in account. |
2104 | LINEUP_WRONG_FORMAT | Lineup must be formatted COUNTRY-LINEUP-DEVICE or COUNTRY-OTA-POSTALCODE |
2106 | LINEUP_DELETED | The lineup you requested has been deleted from the server. |
2108 | INVALID_COUNTRY | The country you requested is either mis-typed or does not have valid data. |
2109 | INVALID_PERSONID | The personId you requested does not exist. |
2200 | STATIONID_NOT_FOUND | The stationID you requested is not in any of your lineups. |
2201 | STATIONID_DELETED | The stationID you requested has been marked as deleted and will be purged. |
3000 | SERVICE_OFFLINE | Server offline for maintenance. |
3001 | SERVER_BUSY | Server is busy processing other requests. Retry. |
4001 | ACCOUNT_EXPIRED | Account expired. |
4002 | INVALID_HASH | Password hash must be lowercase 40 character sha1_hex of password. |
4003 | INVALID_USER | Invalid username or password. |
4004 | ACCOUNT_LOCKOUT | Too many login failures. Locked for 15 minutes. |
4005 | JSON_ACCOUNT_ACCESS_DISABLED | Access to account via JSON has been disabled. Please contact Schedules Direct support: service@schedulesdirect.org for more information or create a support ticket: https://www.schedulesdirect.org/lineupsupport |
4006 | TOKEN_EXPIRED | Token has expired. Request new token. |
4007 | APPLICATION_DISABLED | Application not authorized to use data service. |
4008 | ACCOUNT_INACTIVE | Account inactive. |
4009 | TOO_MANY_LOGINS | Exceeded maximum number of logins in 24 hours. Please contact Schedules Direct support: service@schedulesdirect.org for more information or create a support ticket: https://www.schedulesdirect.org/lineupsupport |
4100 | MAX_LINEUP_CHANGES_REACHED | Exceeded maximum number of lineup changes for today. |
4101 | MAX_LINEUPS | Exceeded number of lineups for this account. |
4102 | NO_LINEUPS | No lineups have been added to this account. |
5000 | IMAGE_NOT_FOUND | Could not find requested image. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6 if you are having issues. |
5002 | MAX_IMAGE_DOWNLOADS | Maximum image downloads reached. Counter resets every 24h. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6 |
5003 | MAX_IMAGE_DOWNLOADS | Maximum image downloads for trial user reached. Counter resets every 24h. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6 |
5004 | MAX_IMAGE_INVALID_URI_ERRORS | Exceeded maximum number of invalid URIs in 24 hours. Application is requesting URIs which do not exist. Counter resets every 24h. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6 |
6000 | INVALID_PROGRAMID | Could not find requested programID. Permanent failure. |
7000 | SCHEDULE_NOT_FOUND | The schedule you requested should be available. Post message to http://forums.schedulesdirect.org/viewforum.php?f=6 |
7010 | INVALID_SCHEDULE_REQUEST | The server can't determine whether your schedule is valid or not. Open a support ticket. |
7020 | SCHEDULE_RANGE_EXCEEDED | The date that you've requested is outside of the range of the data for that stationID. |
7030 | SCHEDULE_NOT_IN_LINEUP | You have requested a schedule which is not in any of your configured lineups. |
9999 | HCF | Unknown error. Open support ticket. |