This article explains the steps required to update Instagram Legacy API to the newer Instagram Basic Display API.
Instagram will disable its Legacy API Platform on June 29, 2020. Originally, it was set to be disabled on March 31, 2020, but the deadline was extended. See the Instagram Developer page for more information on this deadline. https://www.instagram.com/developer

If you are displaying your Instagram feed on a website, then the feed will stop working after the deadline. You will have to update your website to use the Instagram Basic Display API. This article will explain how to display your Instagram feed on a website. The article uses references from https://developers.facebook.com/docs/instagram-basic-display-api/getting-started
In order to display Instagram feed using Basic Display API, you will need to have to the followings:
Once you have #1 and #2, we need to create an access token for the Instagram Account.
We have to use a Facebook account to create an access token for Instagram. You can no longer create access token through your Instagram account like we did previously. The first thing we need to do is create a Facebook App in your Facebook account and add Instagram App as a product to that Facebook app. It involves a number of steps to create an Instagram Access Token. Let's start the steps.







Once the invite is accepted, the Tester Invites page should look like this:

https://api.instagram.com/oauth/authorize?client_id={Instagram App ID}&redirect_uri={Valid OAuth Redirect URI}&scope=user_profile,user_media&response_type=code
For example:
https://api.instagram.com/oauth/authorize?client_id={240439832112592}&redirect_uri=https://www.example.com/&scope=user_profile,user_media&response_type=code

https://www.example.com/?code=AQCpFnU...#_
Authorization code = AQCpFnU...
Open a terminal window and run the following CURL command after replacing the values for app-id, app-secret, redirect-uri and code:
curl -X POST \
https://api.instagram.com/oauth/access_token \
-F client_id={app-id} \
-F client_secret={app-secret} \
-F grant_type=authorization_code \
-F redirect_uri={redirect-uri} \
-F code={code}
The app-id, app-secret, redirect-uri and code values can be obtained from App Dashboard > Products > Instagram > Basic Display
app-id = Instagram App ID
app-secret = Instagram App Secret
redirect-uri = https://www.example.com/
code = Authorization code obtained from previous step
For example:
curl -X POST \
https://api.instagram.com/oauth/access_token \
-F client_id=240139... \
-F client_secret=143ef0... \
-F grant_type=authorization_code \
-F redirect_uri=https://www.example.com/ \
-F code=AQCpFnU...
Once the CURL command is run successfully, a similar output is expected.
{
"access_token": "IGQVJYaUNsMW...",
"user_id": 17841400614018206
}
The access token obtained is a short lived token and will expire in an hour.
In order to check if the short lived access token obtained from the previous step is working, run the following CURL command:
curl -X GET \
'https://graph.instagram.com/me?fields=id,username&access_token=IGQVJYaUNsMW...'
or run the alternate command:
curl -X GET \
'https://graph.instagram.com/{user-id}?fields=id,username&access_token={access-token}'
Once the command runs, the following output is expected:
{
"id": "17841400614018206",
"username": "YourInstagramUsername"
}
The access token obtained in the previous step is short lived and expires in an hour. In order to extend the expiration of the access token we must obtain long lived access token. The long lived access token expires in 60 days and can be refreshed after 24 hours once it is created and before the 60 day. We have to use the short lived access token to obtain the long lived access token.
Run the following CURL command to get the long lived access token:
curl -i -X GET "https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=instagram-app-secret}
&access_token={short-lived-access-token}"
short-lived-access-token = short lived access token must not be expired
instagram-app-secret = App Dashboard > Products > Instagram > Basic Display > Instagram App Secret
For example:
curl -i -X GET "https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=240139...&access_token=IGQVJYaUNsMW..."
The following output is expected:
{
"access_token":"{long-lived-access-token}",
"token_type":"bearer",
"expires_in":5183906
}
The long lived access token can be refreshed once it is 24 hours old and has not expired. The refreshed access token will expire in 60 days and can be refreshed before it expires.
To refresh the long lived access token:
curl -i -X GET "https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token={long-lived-access-token}"
The following output is expected:
{
"access_token":"{long-lived-user-access-token}",
"token_type": "bearer",
"expires_in": 5183944 // Number of seconds until token expires
}
For example: /var/tokens/mytokenfile
The file should have the following file permissions:
-rwxrw-r-x 1 root apache 149 Mar 19 19:48 mytokenfile
You can run the following commands to update the correct file permissions.
chgrp apache mytokenfile - changes the file group to apache user. [Here I am using CentOS Linux, but depending on the Linux distribution you are using, it may be www-data or other web server user.]
chmod 765 mytokenfile - change the file mode so that the group can read and write the tokenfile.
NOTE: You may need to use sudo to run the above commands.
We will be referencing this file in our PHP file to obtain the Instagram feed.
The following two PHP files fetch the Instagram feed from your account and display them on the webpage. InstagramFeed.php is the main file that send the request to get the feed to Instagram using the long lived access token we generated in our previous step. The getFeed.php script references InstagramFeed.php file to display the feed on the webpage. You can modify the code as per your requirement. This is just an example of how we can retried feed from Instagram to our webpage.
NOTE: To reduce call to Instagram server, we are utilizing a cache file to store the fetched feed and use that cache file for 24 hours. The access token file is also updated every 24 hours to generate a new long lived access token. We also have a feed limit of 4 by default so that we do not pull all the feed at once.
Copy the code below and save it as InstagramFeed.php.
<?php
namespace InstagramFeedApp;
define('TWENTY_FOUR_HOURS', 86400);
define('INSTAGRAM_REFRESH_TOKEN_API_URL', 'https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token');
define('INSTAGRAM_FEED_API_URL', 'https://graph.instagram.com/me/media?fields=caption,media_url,media_type,thumbnail_url,permalink');
//fields=id,caption,media_type,media_url,permalink,thumbnail_url,username,timestamp
class InstagramFeed
{
protected $tokenFile;
protected $cacheFile;
protected $feedLimit;
protected $defaultCaption = 'Default Caption';
protected $accessToken;
public function __construct($tokenFile, $cacheFile, $feedLimit = '4')
{
$this->tokenFile = $tokenFile;
$this->cacheFile = $cacheFile;
$this->feedLimit = $feedLimit;
}
public function getInstagramFeed()
{
$feeds = $this->getFeedFromCache();
if (! $feeds) {
$this->accessToken = $this->getAccessToken();
$feeds = $this->sendCurlRequest(INSTAGRAM_FEED_API_URL . "&limit={$this->feedLimit}&access_token={$this->accessToken}");
file_put_contents($this->cacheFile, serialize($feeds));
}
return $this->getFormattedFeed($feeds);
}
private function getFormattedFeed($feeds)
{
$formattedFeed = [];
$feedLimit = $this->feedLimit;
foreach ($feeds->data as $feed) {
$caption = (isset($feed->caption)) ? $feed->caption : $this->defaultCaption;
$image = ($feed->media_type == 'VIDEO') ? $feed->thumbnail_url : $feed->media_url;
$formattedFeed[] = [
'caption' => $caption,
'image' => $image,
'link' => $feed->permalink,
];
}
return $formattedFeed;
}
private function getFeedFromCache()
{
$cacheFile = $this->cacheFile;
if (file_exists($cacheFile)) {
if ($this->isFileModifiedLessThan24Hours($cacheFile)) {
return unserialize(file_get_contents($cacheFile));
}
}
return FALSE;
}
private function getAccessToken()
{
try {
$tokenFile = $this->tokenFile;
if (file_exists($tokenFile)) {
$accessToken = file_get_contents($tokenFile);
$accessToken = trim($accessToken);
if ($this->isFileModifiedLessThan24Hours($tokenFile)) {
return $accessToken;
}
$newAccessToken = $this->refreshAccessToken($accessToken);
file_put_contents($tokenFile, $newAccessToken);
return $newAccessToken;
} else {
throw new \Exception('Token File Missing');
}
} catch(\Exception $e) {
die($e->getMessage());
}
}
private function refreshAccessToken($currentAccessToken)
{
$curlResponse = $this->sendCurlRequest(INSTAGRAM_REFRESH_TOKEN_API_URL . "&access_token=$currentAccessToken");
return $curlResponse->access_token;
}
private function isFileModifiedLessThan24Hours($fileName)
{
$fileModifiedTime = time() - filemtime($fileName);
return ($fileModifiedTime < TWENTY_FOUR_HOURS);
}
private function sendCurlRequest($curlURL)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $curlURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
if(curl_error($ch)) {
echo "CURL ERROR: " . curl_error($ch) . "<br>";
}
curl_close($ch);
return json_decode($response);
}
}
Copy the code below and save it as getFeed.php
<?php
namespace InstagramFeedApp;
require_once 'InstagramFeed.php';
//Required to set these values
$tokenFile= 'mytokenfile';
$cacheFile = '/tmp/feed_cache.txt';
$igApp = new \InstagramFeedApp\InstagramFeed($tokenFile, $cacheFile);
$feeds = $igApp->getInstagramFeed('html');
?>
<div style="padding: 10px;">
<a href="<?= $feeds[0]['link'] ?>"><img src="<?= $feeds[0]['image'] ?>" alt="<?= $feeds[0]['caption'] ?>" width="300" /></a>
</div>
<div style="padding: 10px;">
<a href="<?= $feeds[1]['link'] ?>"><img src="<?= $feeds[1]['image'] ?>" alt="<?= $feeds[1]['caption'] ?>" width="300" /></a>
</div>
<div style="padding: 10px;">
<a href="<?= $feeds[2]['link'] ?>"><img src="<?= $feeds[2]['image'] ?>" alt="<?= $feeds[2]['caption'] ?>" width="300" /></a>
</div>
<div style="padding: 10px;">
<a href="<?= $feeds[3]['link'] ?>"><img src="<?= $feeds[3]['image'] ?>" alt="<?= $feeds[3]['caption'] ?>" width="300" /></a>
</div>
If you access the getFeed.php file from your server on a browser, it should display the images retrieved from your Instagram account.