How To Use The Foursquare API With OAuth And PHP

I started playing with the Foursquare API and one of the first things you need to do is figure out how to authenticate with Foursquare to make calls to the API. It took me awhile to figure this out and start making successful calls, so I thought others could benefit from a detailed tutorial. The goal of this tutorial is to demonstrate how to make calls to the Foursquare API using OAuth authentication and PHP. Foursquare has a helpful API discussion group I recommend checking out. Here are a few starting points that are helpful for this tutorial:

Setup your environment

Here is what you’ll need to complete this tutorial:

To begin, setup a project folder on your web server with the necessary files for this example.

Create a folder called “test” and create files inside that folder called index.php and callback.php. Then download the foursquare-async library (click “Download Source” in the upper right corner). Extract the files EpiCurl.php, EpiFoursquare.php and EpiOAuth.php to the test folder.

You now should have a folder called test that is accessible via a browser that contains these files:

  • index.php
  • callback.php
  • EpiCurl.php
  • EpiFoursquare.php
  • EpiOAuth.php

Note: Depending on your server configuration you may need to manually enable cURL support. I did this example using XAMPP and needed to turn it on. In the php.ini file (C:\xampp\php\php.ini) uncomment the line “extension=php_curl.dll” and then restart Apache. If you get an error like this later in the tutorial it might indicate you need to enable cURL.

Possible cURL error:
Fatal error: Call to undefined function curl_multi_init() in C:\xampp\htdocs\test\EpiCurl.php on line 24

OAuth overview

You can authenticate with Foursquare’s API in one of two ways. The simpler, but less secure way is through basic access authentication. This method requires the user to provide their credentials (username/password) to your application and those credentials get passed right in the web request to the API. It gets the job done, but makes the user’s data more vulnerable. The user is also trusting that the application is storing their credentials securely.

The more secure option we will use in this example is OAuth authentication. OAuth does a better job of protecting the user’s credentials and also gives the user greater control over what applications have access to their account. For example, instead of giving a random application your Foursquare credentials, you instead click on a link within the application that sends you to Foursquare to provide your credentials. Then Foursquare sends you back to the application with appropriate access keys for the application to use. Authenticating this way means that your credentials stay between you and Foursquare. The application you are giving access to only gets the OAuth access keys and doesn’t see or store your actual Foursquare credentials. It sounds complicated, but hopefully this tutorial will clear it up a little. OAuth is becoming more of a standard and as an end user you are probably already authenticating with different applications and web services this way.

Here are the steps for the OAuth workflow that this example will accomplish:

  1. Get request key and secret
  2. Provide a link to the Foursquare authorization page
  3. The user will approve or deny access and be redirected back to your application
  4. Get access key and secret (and store in your application database, but we don’t need to for this example)
  5. Use access key and secret to make API calls

Register with Foursquare to get your key and secret

The first thing we need to do is register our application with Foursquare to get a request key and secret for our application.  Go to http://foursquare.com/oauth/register, login and fill in the required information.

  • Application Name:  OAuth Test
    • Give your application a name (My Foursquare App)
  • Application Web Site:  http://localhost/
    • Provide the site where you will host your application (www.mysite.com/my-foursquare-app)
  • Callback URL:  http://localhost/test/callback.php
    • This is the URL that Foursquare will send the user to after authenticating (www.mysite.com/my-foursquare-app/callback.php)

Click “Register” and Foursquare should generate a new key and secret for your application.  Your key and secret will be different than mine.

You can always return to http://foursquare.com/oauth/ to change these details or reset your key and secret.  At this point your application is registered and you have a key and secret to use.

Add code to the index.php file

The second task is filling in the index.php file with some code.  Open up index.php and add the following code.  Also if you are curious I am using the SyntaxHighlighter Evolved plug-in for displaying code.

<?php

//Put in the key and secret for your Foursquare app
//Your values will be different than mine
$consumer_key = "XB1NE31CJ4U22EF2GA53C4ULR3SL2BG21G1M5VTRCZ3K1XW5";
$consumer_secret = "3RHRD1KJLGFFHKDMD4SCE11NHNDCFUPOIPOQW4VGKLADFKC1";
$loginurl = "";

//Includes the foursquare-asyc library files
require_once('EpiCurl.php');
require_once('EpiOAuth.php');
require_once('EpiFoursquare.php');

session_start();
try{
  $foursquareObj = new EpiFoursquare($consumer_key, $consumer_secret);
  $results = $foursquareObj->getAuthorizeUrl();
  $loginurl = $results['url'] . "?oauth_token=" . $results['oauth_token'];
  $_SESSION['secret'] = $results['oauth_token_secret'];
} catch (Execption $e) {
  //If there is a problem throw an exception
}

echo "<a href='" . $loginurl . "'>Login Via Foursquare</a>";  //Display the Foursquare login link
echo "<br>";
//This is your OAuth token and secret generated above
//The OAuth token is part of the Foursquare link above
//They are dynamic and will change each time you refresh the page
//If everything is working correctly both of these will show up when you open index.php
var_dump($results['oauth_token']);
echo "<br>";
var_dump($_SESSION['secret']);

?>

Now open index.php in your browser and you should see the following, only your two values will be different.

Add code to the callback.php file

Before you go to the login link you created, we need to add code to the callback.php file.  Now open that one and add this code.

<?php

//Put in the key and secret for your Foursquare app
//Your values will be different than mine
$consumer_key = "XB1NE31CJ4U22EF2GA53C4ULR3SL2BG21G1M5VTRCZ3K1XW5";
$consumer_secret = "3RHRD1KJLGFFHKDMD4SCE11NHNDCFUPOIPOQW4VGKLADFKC1";

//Includes the foursquare-asyc library files
require_once('EpiCurl.php');
require_once('EpiOAuth.php');
require_once('EpiFoursquare.php');

session_start();
$foursquareObj = new EpiFoursquare($consumer_key, $consumer_secret);
$foursquareObj->setToken($_REQUEST['oauth_token'],$_SESSION['secret']);
$token = $foursquareObj->getAccessToken();
$foursquareObj->setToken($token->oauth_token, $token->oauth_token_secret);

try {
   //Making a call to the API
   $foursquareTest = $foursquareObj->get_user();
   print_r($foursquareTest->response);
 } catch (Exception $e) {
   echo "Error: " . $e;
 }

?>

Test it out

Now we are ready to try it all out and make a call to the Foursquare API.  This first call is going to bring back your user information.

Open up index.php in your browser again and click the login link.  This is the part where the user leaves your application and goes to authenticate with Foursquare directly.

Notice that your OAuth token is along for the ride in the URL:

Click on “Allow” and Foursquare will send the user to the callback page you created.

If everything worked correctly you will see your user information in the browser.

Try a few more API calls.  This will call back your check-in history:

//Making a call to the API
$foursquareTest = $foursquareObj->get_history();
print_r($foursquareTest->response);

If you want to make a call with parameters it looks like this.  This will get your user information along with your badges and mayorships:

//Making a call to the API
$params = array("badges"=>1, "mayor"=>1);
$foursquareTest = $foursquareObj->get_user($params);
print_r($foursquareTest->response);

As you look through the API documentation you will notice the different methods described like this:

URL: http://api.foursquare.com/v1/venue
Formats: XML, JSON
HTTP Method(s): GET
Requires Authentication: No, but recommended
Parameters:

  • vid – the ID for the venue for which you want information

To call the venue details method above in our example we just need to change a couple things.  We know this method takes in the single parameter vid and we can grab a venue’s ID from its Foursquare URL.  22242 in my example corresponds to the venue Town Talk Diner.  On the next line, combine the HTTP method (GET) with the method name from the URL (venue) to form get_venue.

//Making a call to the API
$params = array("vid"=>22242);
$foursquareTest = $foursquareObj->get_venue($params);
print_r($foursquareTest->response);

Note that every time you go through this process and click “Allow” Foursquare adds another entry for your application.  You can go to your Foursquare settings page to clean these up.  If you were building out an application you would want to save the user’s OAuth information in a database so they don’t have to re-authenticate each time.  For this example the OAuth information is just getting placed in a temporary browser session and thus we have to re-authenticate each time.

Hopefully at this point you are making calls to the API and getting data back.  To go beyond these basic calls refer to the Foursquare API documentation to see everything that is available.  Also refer to the wiki page for the foursquare-asyc library to learn more about how it works.

Share this post:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • email
  • LinkedIn
  • Reddit
  • Slashdot
  • StumbleUpon
  • Technorati
  • Tumblr
  • Twitter
  • Cat
    Hi. I am trying to use your example and it works for me here: http://catherinecolman.com/test/index.php

    but not here: http://sites.asiasociety.org/yoshitomonara/foursquaretest/index.php

    Any thoughts on why this would be? Both applications are registered with foursquare in the same way. Thanks.
  • Really nice post Joe! this was very helpful for me :) thanks!
  • Rao Girish
    Hi Joe,

    I sent you some code through your contact page on this website. I ran into an error at the line:
    $results = $foursquareObj->getAuthorizeUrl();

    in index.php. And the exception is: "Object id #5"
    Seems like $results is not being instantiated properly on that line.

    I've sent you the code, any feedback would be much appreciated! Thank you!
    --g
  • Rao Girish
    I also tried catching the 5 Exceptions you listed, but seems like its going through to the final default Exception clause:

    catch(Exception $e)
  • What would be the next step in saving the token so that the user does not need to re-authenticate?
  • I am getting this error again and again.i just replace the $consumer_key and $consumer_secret with my keys.please help me
    this error occur when i access index.php page.
    Fatal error: Uncaught exception 'EpiOAuthException' in /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php:376 Stack trace: #0 /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php(50): EpiOAuthResponse->__get('oauth_token') #2 /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/index.php(17): EpiOAuth->getAuthorizeUrl() #3 {main} thrown in /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php on line 376
  • Peeze
    As a complete novice I'm having a lot of fun with this, so thanks. Unfortunately though when I point my browser to http://localhost/test/index.php I receive: "Fatal error: Maximum execution time of 60 seconds exceeded in C:\xampp\htdocs\test\EpiCurl.php on line 70" - Might this have something to do with me uncommenting the line "extension=php_curl.dll" for XAMPP?
  • I also keep having this same error, does anyone know what would cause this?
  • Dipak
    can we include html in "venue" or in "shout" . my requirement is to post links if possible
    in foursquare.
  • Jerin
    Please help me, i followed the steps but when i run the index.php file i am getting an fatal error
    Fatal error: Uncaught exception 'EpiOAuthBadRequestException' in /var/www/bbank/foursquare/EpiOAuth.php:373 Stack trace: #0 /var/www/bbank/foursquare/EpiOAuth.php(347): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 /var/www/bbank/foursquare/EpiOAuth.php(51): EpiOAuthResponse->__get('oauth_token') #2 /var/www/bbank/foursquare/auth_authentication.php(7): EpiOAuth->getAuthorizeUrl() #3 {main} thrown in /var/www/bbank/foursquare/EpiOAuth.php on line 373
  • FBP
    Have someone managed to do a custom callback with parameters?. Its supposed to be working with version oAuth 1.0a, but I cant find any llibraries to work with1 1.0a

    any ideas?
  • Lennaz
    maybe im missing some point...
    im not a newbie, and i already have implemented facebook and twitters logins for sites;
    anyway.. i cant really understand the 4sq schema; it keeps ask to allow anytime my application
    and i dont really understand ho to keep the "linked" connection permanent (eg i dont want to click allow if i already did, and if im already logged in 4sq)
  • exactly what I was looking for, great article
  • James
    Followed all your directions, enabled curl and got my Foursquare creds for the app yet when I go to run index.php my web broswer returns the following:

    Parse error: parse error, unexpected '{' in /home/content/s/c/h/schaff424/html/foursquare/test/index.php on line 15

    Not sure what that means since I am a novice with PHP. Any thoughts?
  • Nice tutorial. Well laid out and thanks for the example files. If you have time, you might want to update the screenshots not to use localhost. Might alleviate some of the errors (?)
  • This is the only way to show info about any venue?

    I only need show how many check-ins are in one place. (ex. venue 305154). I tried with jQuery Ajax without success. I dont need any other info. I can this info w/o user auth?

    Thanks
  • Try looking at http://www.placewidget.com/. It's a plugin for showing venue
    data and I don't think it does anything with OAuth. If you pull the
    WordPress copy down I think you can view the code that way.
  • vrush
    Hey...this tut is really cool...helped me a lot.. I followed the steps..but after authentication when I get redirected to "callback.php" i get following error -

    Fatal error: Uncaught exception 'EpiOAuthUnauthorizedException' in "my_server_path"/test/EpiOAuth.php:374 Stack trace: #0 "my_server_path"/test/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 "my_server_path"/test/callback.php(18): EpiOAuthResponse->__get('oauth_token') #2 {main} thrown in "my_server_path"/test/EpiOAuth.php on line 374
  • Hard to tell from the error message. If you want, feel free to zip up all your files and send them from my contact page and I can try them out on my server.
  • "If you were building out an application you would want to save the user’s OAuth information in a database so they don’t have to re-authenticate each time."

    Can you clarify what exactly i should store?
    Store $_REQUEST['oauth_token'] and $_SESSION['secret'] in a database?

    Then how do I call it? Do I take out any of the lines below? Like do I comment out session_start()? Or any of the other lines? (sorry for the amateur programmer questions..i'm trying!)

    session_start();
    $foursquareObj = new EpiFoursquare($consumer_key, $consumer_secret);
    $foursquareObj->setToken('S5NSPDLJZAIPPPESONKBJSC4SQBLUPH3V5P2S3XJON.....','Z0RDL0ZP4534W2NB3PDFU1Z1GFAOIZEOIG3R4E2X.....');
    $token = $foursquareObj->getAccessToken();
    $foursquareObj->setToken($token->oauth_token, $token->oauth_token_secret);
    print_r($_REQUEST['oauth_token']);
    echo " and ";
    print_r($_SESSION['secret']);
    echo " ";
    print_r($token);
    try {
    //Making a call to the API
    $params = array("vid"=>1924283);
    $foursquareTest = $foursquareObj->get_checkins($params);
  • No problem! I'm pretty sure you want to store oauth_token and oauth_token_secret (from line 17 of callback.php). How you store it and retrieve it will depend on the database you're working with. The session code I'm using was just to get this example working. You could take it out once you got your OAuth stuff stored in a database.

    There is a little bit of this briefly discussed at the link below. You may want to put some questions out there as well as you get into other parts of the API.

    http://groups.google.com/group/foursquare-api/browse_thread/thread/743b78ff29ba9256/54d2ccd1208b58e7
  • Cool, thanks for the help. I figured it out ($token->oauth_token and $token->oauth_token_secret are the things to store).

    And as far as I can tell, there's no real way to login again with the 4sq login (such as to change a user's settings within an app) without another oAuth instance (that shows up in the user's foursquare settings page). I ended up just checking to see if the foursquare id already existed in my database, and if it did, I give the user a 'change settings' page versus a 'create new user' page.
  • can you provide example of the code to keep users logged in? Can't seem to figure it out :(
  • Hey Joe, this is tremendously useful. Thank you so much!

    Any tips on where to go to study how to actually work with XML? I don't know what the next step is or how to parse all the stuff foursquare is spitting at me into a usable form!

    Thanks again.
  • Hey,

    You can get data from the foursquare API in either XML or JSON. I heard
    that JSON is easier to work with than XML, so you may want to start there
    and take a look at this:

    http://www.webmonkey.com/2010/02/get_started_with_json/
  • Thanks. What I didn't realize was that using the php wrapper returns php objects. So get_checkins returns a cascaded multi-dimensional array and the parts are accessed by things like:
    print_r($foursquareTest['checkins'][1]['display']);
  • That's great to know. I suppose the wrapper is just saving us a step by converting the XML/JSON for us.
  • Data Anarchist
    Hi there, I am getting the following exception. I have managed to authorise before using the oauth_php library, but wanted to try this one instead - but am not having much joy!

    Do you have any ideas?

    exception 'EpiOAuthException' in /my_web_address/EpiOAuth.php:380
    Stack trace: #0 //my_web_address/EpiOAuth.php(380): EpiOAuthException::raise() #1 /my_web_address/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #2 /my_web_address/EpiOAuth.php(50): EpiOAuthResponse->__get() #3/my_web_address/EpiOAuth.php(50): EpiOAuth::getAuthorizeUrl() #4 /my_web_address/index.php(17): EpiFoursquare->getAuthorizeUrl('oauth_token') #5
  • At what point in the process is the exception happening? Is it when you
    open index.php or is it after you come back from foursquare.com on
    callback.php?
  • Manuel
    hi! my english is poor bat i tray....
    I have the same problem than "Data Anarchist" and it happens when I open the file index.php
  • You can post your index.php file here or send it to me from my contact page (http://www.joesiewert.com/contact/) and I can look at the problem better.
  • Ezhilarasan
    I've followed your tutorial and connected to foursquare. Can you tell me how to do a checkin to foursquare from my site. Thanks in advance.
  • Here is a basic check-in call for this example. Note I'm just using the vid parameter, but the check-in method has additional parameters described in the API documentation.

    //Making a call to the API
    $params = array("vid"=>SOMEVENUEID);
    $foursquareTest = $foursquareObj->post_checkin($params);
    print_r($foursquareTest->response);
  • Brett
    Hmm..any ideas? I'm getting this error:
    Fatal error: Uncaught exception 'EpiOAuthUnauthorizedException' in /MYPATH/EpiOAuth.php:374 Stack trace: #0 /MYPATH/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 /MYPATH/page2.php(17): EpiOAuthResponse->__get('oauth_token') #2 {main} thrown in /MYPATH/EpiOAuth.php on line 374

    Here's the offending code (I got the basic user info to work)
    //this doesn't work'
    try {
    //Making a call to the API
    $params = array("vid"=> 4997892);
    $foursquareTest = $foursquareObj->post_checkin($params);
    print_r($foursquareTest->response);
    } catch (Exception $e) {
    echo "Error: " . $e;
    }


    //this works
    try {
    //Making a call to the API
    $foursquareTest = $foursquareObj->get_user();
    print_r($foursquareTest->response);
    } catch (Exception $e) {
    echo "Error: " . $e;
    }
  • Ezhilarasan
    Thanks for your quick reply. Can you tell me how to check in to a place with latitude and longitude without using venue id. Thanks in advance.
  • Ezhilarasan
    Hi, I've changed the parameters to checkin with latitude and longitude. Thanks
  • Kris
    I've followed your tutorial but when I try to open my index.php I get the following error:

    Fatal error: Uncaught exception 'EpiOAuthException' in /home/content/b/f/s/bfsiteadmin/html/test/4sq/EpiOAuth.php:376 Stack trace: #0 /home/content/b/f/s/bfsiteadmin/html/test/4sq/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 /home/content/b/f/s/bfsiteadmin/html/test/4sq/EpiOAuth.php(50): EpiOAuthResponse->__get('oauth_token') #2 /home/content/b/f/s/bfsiteadmin/html/test/4sq/index.php(17): EpiOAuth->getAuthorizeUrl() #3 {main} thrown in /home/content/b/f/s/bfsiteadmin/html/test/4sq/EpiOAuth.php on line 376

    any ideas?
  • I'm able to get the same error right now and foursquare.com is also down at the moment. I think they have had some hiccups the last couple days, so give it another shot when they are back online again and see if your code works.
  • Hi,

    I followed the steps and replaced the key and secret with ones i generated but i keep getting the same exception everytime i try to load index.php

    Fatal error: Uncaught exception 'EpiOAuthException' in /myserverlocation/foursqtest/EpiOAuth.php:376 Stack trace: #0 /myserverlocation/foursqtest/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 /myserverlocation/foursqtest/callback.php(17): EpiOAuthResponse->__get('oauth_token') #2 {main} thrown in /myserverlocation/foursqtest/EpiOAuth.php on line 376

    help...
  • Ezhil
    hi can you please tell me how to add a venue to foursquare
  • I think this issue might have to do with using 'localhost'

    I did the same (figuring it'd be easier to test locally) and received the same error but when I switched it over to my stage server it worked fine.
  • Adam
    Thanks for this great tutorial. Using these libraries, how do you change the method used and add parameters? For instance, what if I wanted to use the Venue Details method and pass a venue id parameter? Thanks!
  • Hey, I added a venue details example to the main post. Also explained how to use the method descriptions in the API documentation to form calls in this example.
  • This tutorial is so nice^^ actually when I read a wiki in "http://wiki.github.com/jmathai/foursquare-async", I can not understand that how to implement it with PHP. Thank for ur tutorial I can success.
  • Great! I am glad you got it to work.
  • Ezhilarasan
    HI,

    I am following your tutorial its very nice.can you please tell me how to add venues to foursquare from mysite. Thanks in advance.
  • jmathai
    Great detailed post. Linked to this post from the README.

    http://github.com/jmathai/foursquare-async
  • Awesome, thanks!
  • Joe, you did an INCREDIBLE job with this! Really effortless and simple to follow along. I got it working on the first try. Something that I"ve been having a problem with now is understanding which variables to store in MYSQL so that I can make automated calls without re-authenticating every time. Is it just the oauth-token that comes as part of the URL? and the secret as well? So would I basically re-make your "callback" page but pull the variables from MYSQL instead?

    Thanks!
  • Hey, thanks for the great feedback. I'm glad you were able to get it
    working right away. I have not had a chance to go further with the API yet,
    but I think you are on the right track. I'm pretty sure you need to store
    the OAuth token you get back and the secret (which is currently stored in
    the session) in your database. Then you should be able to make calls
    without re-authenticating.
  • Avi
    hi, i am trying to do this, but i find that there is a need for an exchange of credentials using xauth? any ideas in how to implement the function?
  • jason z
    I, too, am getting the EpiOAuthException error. I echoed the error code and it's 500, so I believe my credentials aren't the problem:

    Fatal error: Uncaught exception 'EpiOAuthException' in D:\www\L3D\footprint\EpiOAuth.php:378 Stack trace: #0 D:\www\L3D\footprint\EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 D:\www\L3D\footprint\EpiOAuth.php(50): EpiOAuthResponse->__get('oauth_token') #2 D:\www\L3D\footprint\index.php(14): EpiOAuth->getAuthorizeUrl() #3 {main} thrown in D:\www\L3D\footprint\EpiOAuth.php on line 378
  • I am getting this error again and again.i just replace the $consumer_key and $consumer_secret with my keys.please help me
    Fatal error: Uncaught exception 'EpiOAuthException' in /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php:376 Stack trace: #0 /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php(346): EpiOAuthException::raise(Object(EpiCurlManager), false) #1 /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php(50): EpiOAuthResponse->__get('oauth_token') #2 /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/index.php(17): EpiOAuth->getAuthorizeUrl() #3 {main} thrown in /mounted-storage/home110a/sub007/sc65597-FTSX/sailsms.com/myinn/EpiOAuth.php on line 376
  • jason z
    This was a "data consistency bug" that affected new API customers:

    http://groups.google.com/group/foursquare-api/browse_thread/thread/bf8e901c91252a18

blog comments powered by Disqus