Chrome IG Story — Bribing the Instagram Story API with cookies 🍪🍪🍪

Alec Garcia
5 min readAug 11, 2016

--

EDIT: Due to a Cease & Desist letter from Facebook, I have taken down the Chrome extension and the GitHub repo and do not condone breaking Instagram’s Terms of Service by accessing the private API endpoints mentioned in this article.

Instagram Stories recently came out, giving Instagram users a nearly identical experience as Snapchat Stories. It took Instagram 2 years to build their first web app, and then another 3 years to implement web search. It will probably be a while, if at all, before Instagram brings Stories to the web, so I thought I’d do it myself.

I knew the best way to bring Instagram Stories to the web was through a browser extension. I’m an avid Chrome user, and Chrome extensions are pretty powerful, so I opted to build a Chrome extension to get the job done.

Chrome extensions allow you to inject code into the page, so all I needed was the data for my friends’ Stories and I could construct a UI that displays them all in a row, then inject it to the top of the feed, just like in the mobile app.

So how do I get the data for my friends’ Stories? Well, Instagram’s Developer API doesn’t have an endpoint that supports such data, so I had to reverse engineer the internal API endpoint for Stories.

By using a proxy like Charles Proxy, one can view the decrypted SSL network requests and responses that are sent and received to one’s phone. After getting Charles up and running, I opened up Instagram and immediately saw that Stories were being retrieved, and I was able to see the data transmitted by its endpoint.

Getting your friends’ Instagram Stories

To get the list of Stories, simply make a GET request to:

https://i.instagram.com/api/v1/feed/reels_tray/

This endpoint returns all the data associated with the “tray” or bar at the top of your feed with all your friends’ profile pictures.

Now, what about authentication? This is where those sweet cookies 🍪🍪🍪 come in. Instagram’s desktop website saves cookies about your session to authenticate your requests. Since Chrome extensions are awesome, we can access the cookies if we request permission to access Instagram.com’s data in our extension.

But how do we send these cookies in our request? Good question. Normally when you make a request from the browser like an AJAX request (XMLHttpRequest), you can’t modify the headers. With our Chrome extension, we can use the ‘chrome.webRequest’ API to listen for requests, and then hook into the ‘onBeforeSendHeader’ event and intercept the headers, allowing us to modify them before sending the request.

We can retrieve two Instagram cookies called ‘ds_user_id’ and ‘sessionid’ using the ‘chrome.cookies’ API and then inject them into our request’s headers. The Instagram API will pleasantly take our cookie peace offering and give us back our Stories in return. 😀

Now that we have our Stories data, we can iterate through every friend, generate an image with their profile picture, give it a nice circular border, and append them all in a row to create our Stories “tray”.

The ‘reels_tray/’ endpoint only returns new content, aka images/videos you haven’t yet seen, which are distinguished by the colorful orange-pinkish border around the user’s profile picture that indicates new Stories. In order to make Chrome IG Story fully functional and allow users to view the Stories of users they have already seen (old content), I had to find a way to retrieve a person’s full story, not just their new stuff. Luckily, there was an endpoint for exactly that.

Getting a specific user’s Story

To get a list of all the images and/or videos that are currently on the user’s Story, make a GET request to:

https://i.instagram.com/api/v1/feed/user/USER_ID/reel_media/

Now you can click on a user whose Story you have already seen, and their whole Story will be retrieved and shown in the gallery.

Permalinks?

It appears that Instagram currently does not delete photos/videos off their server neither when the Story image/video expires (after 24 hours) nor if a user manually deletes the Story image/video. In other words, the link to the image/video will continue to work even after the Story has expired or a user deletes it.

In the image galley for Chrome IG Story, you can right click the image/video and “Copy Image/Video Address” to grab the link of the photo or video and share it. However, be respectful of the user’s privacy when sharing the URL, since once someone has the link, the link is forever.

Download ALL! the Stories 😁

Instagram might be saving all your photos and videos on their server so they can introduce an “On This Day” feature for your Instagram Stories in a year, but I feel like they should be moving those files to an archive somewhere, not keeping them hosted under the same link. Until Instagram fixes this, if they even do, feel free to be a creep and hoard all your friends’ Story media. With Chrome IG Story, you can right click the icon of an Instagram user to download their Story — all the photos and videos on that user’s Story will be zipped up and the download will start.

Install Chrome IG Story Extension

Are you ready to experience your friends’ Instagram Stories in your browser? You can install the Chrome extension from the Chrome Web Store:

Open Source on GitHub

Curious how Chrome IG Story works? Feel free to check out the source code, and even submit pull requests if you have a bug fix or feature request.

--

--

Alec Garcia

Code 👨‍💻 and coffee ☕️. Software Engineer at Google.