freeCodeCamp Challenge Guide: Use the Twitch JSON API

Use the Twitch JSON API

Problem Explanation

Update December 28, 2018: Twitch has updated their API a few times since we wrote this. The latest version of their API is here.

Due to a change in conditions on API usage, requires an API key, but we’ve built a workaround. Use and you’ll still be able to get account information, without needing to sign up for an API key.

If you’re trying to tackle this challenge with jQuery’s $.getJSON() method, chances are you’ll get an error message concerning Cross-Origin Resource Sharing (CORS).

The easiest way to resolve this is to use jQuery’s JSONP capabilities. From the Twitch API’s readme page:

All API methods support JSON-P by providing a callback parameter with the request.

Also the jQuery documentation states:

If the URL includes the string “callback=?” (or similar, as defined by the server-side API), the request is treated as JSONP instead.

Here’s an example call to fetch Free Code Camp’s Twitch channel data:

$.getJSON('', function(data) {

JSONP is considered insecure according to Wikipedia, but should be sufficient for our purposes. For a detailed discussion on Twitch’s CORS restriction, please read issue #133 on the Twitch-API repository.


Hey there!
This is good info, BUT, I am not using the JQuery. How do I do the same with vanilla JS? :slight_smile: Any info on that? Been struggling with this for way longer than I would like to. Help…?


JS version of getJSON


var request = new XMLHttpRequest();'GET', '/my/url', true);

request.onreadystatechange = function() {
  if (this.readyState === 4) {
    if (this.status >= 200 && this.status < 400) {
      // Success!
      var data = JSON.parse(this.responseText);
    } else {
      // Error :(

request = null;


var request = new XMLHttpRequest();'GET', '/my/url', true);

request.onload = function() {
  if (request.status >= 200 && request.status < 400) {
    // Success!
    var data = JSON.parse(request.responseText);
  } else {
    // We reached our target server, but it returned an error


request.onerror = function() {
  // There was a connection error of some sort



var request = new XMLHttpRequest();'GET', '/my/url', true);

request.onload = function() {
  if (this.status >= 200 && this.status < 400) {
    // Success!
    var data = JSON.parse(this.response);
  } else {
    // We reached our target server, but it returned an error


request.onerror = function() {
  // There was a connection error of some sort



I’ve been trying to understand the IE10+ version, but I’m struggling.

How does this work? I’ve been trying to find a way to put the initial request into a function so you could put multiple url’s in there, but that messes up the onload method. How could you do that?

Hi Rafase,

I have followed your advice (more or less) and I am doing fine with the twitch challenge. I do get the data and NO problem with CORS. I don´t even need to use JSONP, which is great. However, I am struggling BIG TIME on a silly issue:

I have constructed a function that does XMLHttpRequest (like in your example), and I want to use the function anytime I need such a request inside other functions. So anytime I need a certain Json I invoke that function passing as an argument a variable called url that contains an url. So far so good! The problem is that function does get the Json and it stores it in a variable (called data) but I am incapable of using that variable outside the function. In other words I would like the XHR to return a variable to be used in other functions. Does it make any sense?

This is my code… how could I use variable data from the XHR function in the function called misLlamadas() ?? Please, help!


Sorry to bother you. Is your reply addressed to me? I guess it is not, but in case it was I just wanted to acknowledge that I have read it and thank you. My problem is not related to json, or Jsonp, or xmlhttprequests, or receiving the data or parsing it. I do that already. My problem is not understanding how to properly return a value out of a function… so a different function can use it.


I would do it like this (data in console):

And you should really post the code and not screenshots.


I guess I don’t understand what you mean. But what I did is providing a third argument for myRequest so you can send whatever callback you need to receive data

function myRequest(url, tipoRequest, callback) {
  var rawData, data;
  var request = new XMLHttpRequest();"GET", url, true);
  request.onload = function () {
    if (request.readyState === 4 && request.status === 200) {
      rawData = this.response;
      data = JSON.parse(this.response);

1 Like

Thank man! You are right… I forgot how to paste code (in the way it looks good) so I pasted an image because it looked better than plain text. I will search for that feature.

On the other hand I will check your solution now, what I have seen so far definitively goes in the right direction. I do not know what the fat arrow does (don´t remember) neither the .then method but it looks like the right time to read about them. Will come back with comments to your solution.

Thanks again

Hi fhdhsni!

Thanx man. What you have suggested is adding a parameter, which basically takes data INTO the function when you invoke it and pass an argument. What I am looking for is the exact opposite. In your example the data from json would be saved in the variable data.
I would like to use said variable outside of myRequest because myRequest should only be a requester (like a messenger) that goes to the Internet for data and comes back and delivers it to other functions that have the role of manipulating said data.

Update: Now that I think about it, from your solution we could get rid of callback as a parameter, but still inside myRequest we could invoke another function and pass variable data as an argument. Formally I would have reached my goal of using exterior functions, but my goal is to make of myRequest just a messenger that provides data to functions that made use of it. If you are curious the solution provided by jenovs looks quite good (haven`t tested yet).

I’m confused. The first post to this topic has a post date of Jul 2, but the text states “Update Sep 29, 2016” and then goes on to say, don’t use the twitch tv api.

Am I correct that we should no longer use the twitch tv api for this project?

It seems that we should now hardcode a variable into our project which i guess simulates what would be returned, had we called the twitch api?

Finally, I don’t see anything on the twitch api developers pages indicating an api key is required.

as you can see, I’m very confused as to how to proceed on this project. Any insights on how to proceed would be appreciated.


hi gobees,

  1. You are correct. As I see it, these API challenges (not only the twitch one) have 2 parts… one is getting the data you need/want from the Api provider, the second one is to “play” with that data and present it to the users of your web app. Unfortunately Twitch is making a lot of changes that are not very well implemented and documented, and FCC is dealing as it can with them.
    FCC provides a Json so you don´t kill yourself trying to figure out how to extract the data through the API. This way you skip part one of what i mentioned in number 1, and work on part two, presenting the data. You can go that way, and it will be ok. I am not using the json because I am having success getting the data though the API (so far).

  2. You do not need and Api Key, in this case. What you need is a client ID. which you insert in the url when you make a request with JQuey, or in my case with pure Javascript. This link takes you to the explanation on how to get authorisation to use request. Please, note that it talks about client IDs, but also about a second and deeper kind of authorisation through “tokens”. You need first to become a member of twitch, with the usual user/pass, and then follow the link above.

What most people do is to use the array of users/channels provided by FCC on the presentation of the challenge. I am using an array of the channels I am following myself (not that I am a fan of twitch :slight_smile: ).

I am not sure I have been of much help…


you are helping and I do have a client ID. then I read the “update” at the top of this thread and read “API key” and decided I had to go do that now as well.

I’m reading that the curriculum is about to change and this project will not be around much longer. Unfortunately, it’s my last of the group so I guess I have to press on.

it’s kind of frustrating. Learning should not be impaired by problems with the learning material.

1 Like

you are right… :slight_smile: sooo right… but it seems it is the way things work and we better get used to it. In reality the whole internet if full of bad quality information. For me it was a surprise to read how a lot of people struggles learning python because it is not well documented… I though… how can a programming language be invented and not documented???

I guess that there are so many things to work on, mistakes to correct, things to implement that it is hard to stop and document. On the bright side… it amazes me how many people is willing to help and look into our boring and bad written code!

Let the force be with you!


Does this even work anymore? I just tried it with:

$.getJSON(``, data => {

and once again I get ‘Bad request’ ‘No client id specified’


I’m using this:

url: ‘’ + channel[15] ,
headers: {
“Client-ID”: your client id

and it’s working.


you’re gonna need a client id and either include in URL or in a header

Yea but I thought they said not to use your client id on codepen? I’d rather not have my twitch account banned for a ton of people copy/pasting my id or something =S

as this is a front end project, I think it is quite acceptable to use the json data provided by fcc (op 2nd paragraph). Boss man mentions this challenge is on the list to be retired, in the post addressing the api change.

JSONP is not XMLHttpRequest (ajax). In vanilla JS it’s something like this:

  const script = document.createElement("script");

  window.myJsonpParser = function (data) { console.log(data); }; 

  script.src = ""


As you can see all it does is making a script tag and append it to the page (DOM). As soon as appending happens browser tries to fetch to data. Server knows that we want the data to be wraped inside myJsonpParser because we provided the callback=myJsonpParser query string. So it responses with something like:

jsonpParser(["cool", "data", "here"]);

Browser calls jsonpParser with the received data. Notice jsonpParser should be global, that’s why I used window.myJsonpParser in case you’re using IIFE.
Don’t forget to delete the appending script tags when you are done.