Instagram API implementation in PHP

NOTICE: Thanks to everyone interested in this. Sadly, I haven’t had the time that I would like to dedicate to this blog lately. I invite you to head directly to the Github Project Issue Tracker where a more fluid discussion can take place and a bigger community can participate and help with your particular issues.

 

Instagram recently released an official API. Initially, they had implementations in Python and Ruby, so I decided to build mine in PHP with a little help from Zend Framework.

In order to use the official API, you have to sign up first for a client key at http://instagr.am/developer/. You will need to register a new client or use the data from an existing one, just keep in mind these are the important data that you need before you can interact with the API:

Client Id: let’s call it a public key. It is necessary so the API knows your application. This is public available information, for the purpose of the example provided with my implementation we are going to query Instagram’s service directly using the client key as part of the URL.

Client secret: this is the private key that once paired with the client id is exchanged with Instagram’s service. The client secret needs to be private, but you have to make it available in some form inside your code so it can be sent and to get the authentication token back.

Callback url: maybe on of the most important aspects in this example. Make sure the callback URL is exactly the same where you are going to put the script that acts as an entry point for the Instagram callback. For this particular example, this script is going to be called “instagram.php”, meaning that you’ll have to point Instagram to something like http://example.com/instagram.php.

So this is as easy as one, two, three.

1. Grab the code from GitHub in you preferred format: zip or tar.gz and Unpack it in the same folder you told Instagram your callback was going to live.

2. The example we create in this post, authenticates and displays the most popular photos according to the data sent back by the API. The implementation provides access to all public methods, so you can create you own stuff. Amongst others, you can search for media, perform ‘follow’ actions or search media by location.

3. Just make sure to modify the code, so you can put your own client properties in the $config array at the beginning of the file:


/**
* Configuration params, make sure to write exactly the ones
* instagram provide you at http://instagr.am/developer/
*/
$config = array(
'site_url' => 'https://api.instagram.com/oauth/access_token',
'client_id' => '', // Your client id
'client_secret' => '', // Your client secret
'grant_type' => 'authorization_code',
'redirect_uri' => '', // The redirect URI you provided when signed up for the service
);

And now, the code of the instagram.php script:

require_once 'Instagram.php';

/**
* Configuration params, make sure to write exactly the ones
* instagram provide you at http://instagr.am/developer/
*/
$config = array(
'site_url' => 'https://api.instagram.com/oauth/access_token',
'client_id' => '', // Your client id
'client_secret' => '', // Your client secret
'grant_type' => 'authorization_code',
'redirect_uri' => '', // The redirect URI you provided when signed up for the service
);

// Instantiate the API handler object
$instagram = new Instagram($config);
$popular = $instagram->getPopularMedia();

// After getting the response, let's iterate the payload
echo "
<ul>\n";
$response = json_decode($popular, true);
foreach ($response['data'] as $data) {
$link = $data['link'];
$caption = $data['caption']['text'];
$author = $data['caption']['from']['username'];
$thumbnail = $data['images']['thumbnail']['url'];
?>
	<li><a href="<?= $link ?>"><img title="<?= $caption ?>" src="<?= $thumbnail ?>" border="0" alt="" width="150" height="150" align="absmiddle" /></a> by <!--?= $author ?--></li>
<!--?<br /--> }
echo "</ul>
\n";

Finally, point you browser to the authorization URL and enjoy your coding!

https://api.instagram.com/oauth/authorize/?client_id=CLIENT_ID&redirect_uri=REDIRECT_URL.

You can get more details about manipulating the API at http://instagr.am/developer/

55 thoughts on “Instagram API implementation in PHP

  1. Pingback: Noticias 28-Febrero-2011 - La Web de Programación

  2. Brent Shepherd

    Thanks Mauricio for doing this up & putting it on Github. I was just about to start work on one but figured I’d do a search first to see if someone else had already done it.

    I’m looking into building a real-time photo printing service for Instagram – http://inkagram.com

    What are you going to build?

    Reply
  3. Mauricio Cuenca Post author

    Thanks for passing by Brent, I just checked your idea and I loved it along with the design. I don’t have any plans right now on building a product based on my implementation. I just want to keep working on it and make it really robust so it can be the reference library for PHP developers who want to connect their project with Instagram. I’m the process of sending the proposal to Zend Framework so it can be part of their framework. I also have in mind creating a package for PEAR and building a standalone version that does not require any library apart from CURL.

    Don’t hesitate to send me your comments and feedback regarding your experience with my code, I would be more than happy to help and build a solid library.

    Reply
  4. Joko

    Hi Mauricio,
    Thanks for the beautiful package. I have few questions regarding the package, perhaps you can enlighten me :)
    I was reading the instagram api, there are 2 ways to connect the server

    //explicit call
    https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code

    //implicit call
    https://instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token

    According to your code, I should try the token, which gives me blank screen (only returns me access_code). But, if I use the explicit call, it returns me all the images (with CODE string).

    My question is, how to retain the access code through out the site?

    I’m a novice, please bear with me.
    Thanks,
    Joko

    Reply
  5. Mauricio Cuenca Post author

    Hi Joko, if you grab the updated code from github, you’ll find two new methods I added so you can grab the access token upon the initial request and use it subsequently for all additional requests. According to Instagram’s documentation, the token doesn’t expire. Once you have the new code, you can do something like this:

    // After the first request, you grab the access token
    $instagram = new Instagram($config);
    $popular = $instagram->getPopularMedia();
    $accessToken = $instagram->getAccessToken();

    // And then use it in every subsequent request
    $instagram = new Instagram($config);
    $instagram->setAccessToken($accessToken);
    $popular = $instagram->getPopularMedia();

    Reply
  6. Joko

    Mauricio,
    you are my hero!
    Thanks a bunch. I’ll download it and play around with it.

    FYI: the zend library won’t work if I only download the Zend/Http… it throws me error after error. I fixed it by downloading whole Zend library.

    I’ll post updates with my progress, if you don’t mind.

    :)

    Reply
  7. Thomas

    Hey Mauricio,

    the above example doesn’t work for me, any suggestions?

    Here’s the message I get after executing:
    $instagram = new Instagram($config);
    $popular = $instagram->getPopularMedia();
    var_dump($popular);

    “{“meta”: {“error_type”: “OAuthParameterException”, “code”: 400, “error_message”: “\”client_id\” or \”access_token\” URL parameter missing. This OAuth request requires either a \”client_id\” or \”access_token\” URL parameter.”}}”

    Reply
  8. Mauricio Cuenca Post author

    Hello Thomas, the example is pretty straightforward it should work right out of the box.
    Do you have your code in the same address you set up as the “callback_uri” param? Looks like your trying to get the popular media from some other address. Also, make sure that you have cURL enabled in your server.

    I’m about to release a new version of the implementation with a more detailed example. Stay tuned for the new update!

    Reply
  9. Fran Rodas

    Don´t work you code:

    Fatal error: require_once() [function.require]: Failed opening required ‘Zend/Loader.php’ (include_path=’.:/usr/local/php52/pear’) in /home/orlaspro/public_html/Zend/Http/Client.php on line 27

    Seem to be missing files that are not included in the Zend folder. I even tried to restore the missing files and yet still fails the example

    Reply
  10. Marcy Sutton

    Seems pretty silly to have to download the whole Zend library, you should really mention that as a dependency in your blog post. It is totally unnecessary to include Zend Framework just for one library definition, in my opinion — surely there must be a way to free your script from that requirement…?

    Reply
  11. Mauricio Cuenca Post author

    @Marcy, The version that depended on ZF was the first one and I used it to deliver something fast. Now, I added a really simple HTTP client implementation based on cURL and there’s no need to download the Zend Framework library.

    @Thomas, thanks for sharing instrapress. Looks really neat! My idea is to have something that covers a broader spectrum. I have done several changes to my classes since the last time you checked them. I’ll create another blog post explaining the new functionality.

    Thanks!

    Reply
  12. Toki

    Hello Mauricio

    Thanks for great work. somehow I get same error as everybody else.

    {“meta”: {“error_type”: “OAuthParameterException”, “code”: 400, “error_message”: “\”client_id\” or \”access_token\” URL parameter missing. This OAuth request requires either a \”client_id\” or \”access_token\” URL parameter.”}}

    I tried on 2 different server, medial temple and bluhost. CURL is working on both, same issues. Hmm what am I doing wrong? I just downloaded latest from githum.com as well!!

    Reply
  13. Toki

    Hello Mauricio

    I posted previous post, and somehow I got it working by adding “display=touch” into $_endpointUrls['authorize'].

    Just like this.
    ‘authorize’ => ‘https://api.instagram.com/oauth/authorize/?display=touch&client_id=%s&redirect_uri=%s&response_type=%s’

    Hope it helps you and everybody else using your code.

    Thanks

    Reply
  14. undaunted

    This is wonderful and I truly appreciate your initiative. Unfortunately I am getting an error Warning: Invalid argument supplied for foreach() in callback.php on line 55. Any ideas would be mucho appreciated.

    Reply
  15. Pandav

    Hello Mauricio,

    Thanks for wonderful package, I have a doubt : I would also like to clarify that we would like the option to change (the code) what tag Instagram users attach to each photograph they upload. And not just location. For example, if we chose the word #blue all users that tag their photo with #blue will appear in real-time.
    and like Instagram demo site generate dynamic pictures randomly. How could i do it on php ?

    Reply
  16. Mauricio Cuenca Post author

    Hello Pandav, there are three different methods to kind of accomplish what I guess you’re looking for:

    You can use getTags($tagName), getRecentTags($tagName) or searchTags($tagName). Each method is self explanatory, the code also mentions the purpose of each one.

    Keep in mind that my code doesn’t interact with the real-time API, just the regular one. But feel free to modify the code and adapt it so it accomplishes this purpose, should be somewhat easy to do.

    Reply
  17. @Joel_Hughes

    Hi,
    thanks for this – it’s always nice to pick up a library to help.

    One question – how do you handle pagination? Looking at the API docs it’s as if you need to deal with the “next_url” parameter fed back in results?

    Joel

    p.s. good work!

    p.p.s the api allows you to pass “SELF” in to getUser; I think you assume it’s an int

    p.p.p.s getUserRecent (and, I guess, others) has a “count” parameter as well (restricting number of results coming back) handy!

    Reply
  18. giotis

    Hi Mauricio,

    thanks for your work but still receive the following error when I try the example.php script.

    I put the Client ID and secret and redirect URI as received from instagram develop site.

    Warning: Invalid argument supplied for foreach() in /home/………../callback.php on line 55

    Any help?

    Gracias!

    Reply
  19. Pingback: Instapress | WordPress Designer

  20. lisa

    @Mauricio I have same warning but on a different line when its time to load photos. Cant figure it out. So annoyed. Anyone know why this happens from time to time?

    Warning: Invalid argument supplied for foreach() in

    Reply
  21. Ralph

    Thanks your code works fine!

    Could someone help me out with the following:

    Iam trying to implemt this code in to my cms. To allow users to publish there photos on there website.

    So Iam trying to get the username of that user so my cms can list there photos instead of most popular photos.

    Is that even possibe? In the “example.php” there are asked to login. Then they are redirected to the defined url. There an id shoud be found?
    Anyone?

    Anyonee

    Thanks

    Reply
  22. Ralph

    Iam a little bit futher..

    $userdata=$instagram->getUser($_SESSION['InstagramAccessToken']);
    $userdata = json_decode($userdata, true);
    //shows fullname
    print “full_name=”.$userdata['data']['full_name'].”";

    But underneath function doesnt require a user id?

    public function getUserFeed($maxId = null, $minId = null) {
    $endpointUrl = sprintf($this->_endpointUrls['user_feed'], $this->getAccessToken(), $maxId, $minId);
    $this->_initHttpClient($endpointUrl);
    return $this->_getHttpClientResponse();
    }

    Reply
  23. Guilb

    Hi,

    Thanks for your script. That help me a lot but….. :-) I got a problem for modify users relationship.

    I use : $followtest =$instagram->modifyUserRelationship(an_id,’follow’); but i got this message :”APIInvalidParametersError [code] => 400 [error_message] => please supply action=approve,ignore,follow,block,unblock,unfollow )"

    Thanks for your help with advance...

    Guilb

    Reply
  24. pet supplies plus

    So Iam trying to get the username of that user so my cms can list there photos instead of most popular photos.

    Is that even possibe? In the “example.php” there are asked to login. Then they are redirected to the defined url. There an id shoud be found?
    Anyone?

    Reply
  25. Andrey Lima

    Hi Mauricio,

    I would like your help. How could I change the display of images of “popular” for profile pictures attached for example? I tried just changing the “getPopularMedia” by “GetRecentMediaForUser” but without success.

    Reply
  26. Mauricio Cuenca Post author

    @Dennis, replace the line:
    $popular = $instagram->getPopularMedia(); with: $tags = $instagram->getTags(‘example’); and that should do the trick!

    @Andrey, you can retrieve the latest media for a given user with the getUserRecent() method.

    Reply
  27. Andrey Lima

    I made this way was not successful:

    / / Instantiate the object handler API
    Instagram Instagram $ = new ($ config);
    $ $ = accessToken Instagram-> getAccessToken ();
    $ _SESSION ['InstagramAccessToken'] = $ accessToken;

    Instagram $-> setAccessToken ($ _SESSION ['InstagramAccessToken']);
    $ = $ Instagram popular-> getUserRecent ();

    Reply
  28. Andrey Lima

    Hi Mauricio,

    How do I use this method of display instead of presenting only the most popular images as in the example?

    / **
    * Get the most recent media published by a user.
    * @ Param $ id. User id
    * @ Param $ maxId. Average return after this maxId
    * @ Param $ minId. Average return before this minId
    * @ Param $ maxTimestamp. Average return before this UNIX timestamp
    * @ Param $ minTimestamp. Average return after this UNIX timestamp
    * /
    public function getUserRecent ($ id, $ maxId =”, $ minId =”, $ maxTimestamp =”, $ minTimestamp =”) {
    $ endpointUrl = sprintf ($ this-> _endpointUrls ['user_recent'], $ id, $ this-> getAccessToken (), $ maxId, minId $, $ maxTimestamp, $ minTimestamp);
    $ this-> _initHttpClient ($ endpointUrl);
    return $ this-> _getHttpClientResponse ();
    }

    Reply
  29. Gaurav Bains

    Hi Mauricio,
    Thanks for this awesome API.
    I have got most of the functions running properly, but for POST functions, i get Permissions error, like when following other user, i get error “This request requires scope=relationships, but this access token is not authorized with this scope. The user must re-authorize your application with scope=relationships to be granted write permissions.”

    I know, i need to get Scope (Permissions), as relationships+comments+likes, but how & where to do that, i certainly don’t know.
    Please help

    Reply
  30. Ben Baudart

    Dear Mauricio,

    first of all, thanks for the library, so far it works great for my current project.
    One thing though… I couldn’t find a way to get the authenticated user informations (ID, name),
    as I only found a function to get infos about a user with a known id.
    And using getUser(“self”) didn’t seem to work…

    I added this in the $_endpointUrls array
    ‘user_self’ => ‘https://api.instagram.com/v1/users/self/?access_token=%s’,

    and this function
    /**
    * Get basic information about the authenticated user.
    */
    public function getUserSelf() {
    $endpointUrl = sprintf($this->_endpointUrls['user_self'], $this->getAccessToken());
    $this->_initHttpClient($endpointUrl);
    return $this->_getHttpClientResponse();
    }
    And it worked for me…

    Did I miss anything?
    Thanks,

    Ben

    Reply
  31. Mauricio Cuenca Post author

    Hi Ben, I’m not sure if I follow you correctly. There are two method for retrieving users data in the API:
    1. getCurrentUser() which returns all the data for, obviously the authenticated user, and…
    2. getUser(id) for getting information about a particular user with a known id

    AFAIK, the ‘/users/self/’ endpoint is not documented, but it seems to work and gives you more information about the current user. If that’s the case, I think your approach is correct.

    Thanks for passing by!

    Reply
  32. laeeq

    Hi,

    Thanks for this super script, but i can’t Get the current user id, i use getCurrentUser(); but i have no result…

    Do you have any idea ?

    Reply
  33. Rachelangelo

    Hi Mauricio!

    I’m testing your code and I have two questions:

    - What about pic.php? It seems not to be included at the sample
    - After retrieving a tag via getTags, how can I get related pics?

    I’ll apreciate your answer.

    Thx!

    R

    Reply
  34. rufi

    lovely article ,
    I have a question , I want to get user information on every page load ,
    But, here i am not able to get user info ,
    but once i re-click on permissions url then that url redirect me to same page then I will be able to get user info.

    please let me know how can i find user info and access token on every page load like facebook connect

    Reply
  35. mistered

    Hi Mauricio,

    Could you provide us an exemple to use the getUserRecent function.

    I try $popular = $instagram->getUserRecent(1574083);

    With no success.

    I’ll apreciate your answer.

    Thx!

    Reply
  36. jakenow

    sorry Mauricio wrong email in that last comment, please email me at this one instead . again i would like to hire you for a job but there is no email for you listed anywhere on this website or on twitter so i hope u receive this message

    Reply
  37. Chris

    When attempting to return the results of all the users photos I am unsuccessful with the endpoints you have in the script. What would be the best way to return all of the users photos in the array?

    Reply
  38. Kevin Munro

    Hi Mauricio,

    Thanks for making this code available, I was able to get up and running with my test php project really quickly :)

    Cheers

    Kevin.

    Reply
  39. Pingback: Instapress | WP Plugin Directory

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>