Facebook Places v.s. FourSquare API

I’ve been doing lately lots of work related to location and geocoding and had change to do integration to both Facebook Places API and Foursquare API. Here is simple side-by-side comparison that you find useful.

Both API’s are JSON based HTTP REST interfaces. They offer place search by query string (e.g ‘pizza’), coordinates (lat & lon) and radius of search.  Authentication is based on OAuth, though FourSquare can be be also used without user token, within rate limit.

Facebook Places API

Places API is a part of the larger Graph API and enables places query in addition to people, objects, etc…

Simple example query with keyword pizza around New Jersey.

https://graph.facebook.com/search?q=pizza&type=place&center=40.82,-74.1&distance=1000&access_token=<<oauth access token>>

Example return value JSON

{u'data': [{u'category': u'Local business',
               u'id': u'154150281291249',
               u'location': {u'city': u'Wallington',
                   u'latitude': 40.843026999999999,
                   u'longitude': -74.105144999999993,
                   u'state': u'NJ',
                   u'street': u'435 Paterson Ave',
                   u'zip': u'07057-2202'},
               u'name': u"Marina's Pizza & Restaurant"},
             {u'category': u'Local business',
              u'id': u'116347165056160',
              u'location': {u'city': u'Carlstadt',
                   u'latitude': 40.841267000000002,
                   u'longitude': -74.101149000000007,
                   u'state': u'NJ',
                   u'street': u'326 Garden St',
                   u'zip': u'07072-1626'},
              u'name': u'Garden Pizza Ice Cream & Cafe'},

Note that as of time of writing,  Places API does not work outside United States. if you try to call it from IP address outside US  you’ll probably get following cryptic error response:

   "error": {
      "type": "OAuthException",
      "message": "(#603) The table you requested does not exist"

API is pretty fast but data quality is mediocre as its best and you pretty much get only the name, location and some sparse address data that might be enough.

  • API does not support unauthenticated requests
  • Results have often duplicates, typos and include strange places that seem to have been automatically scraped from some  database.
  • Rate limit is not problem. Facebook does endorse some kind of (high) rate limit, but it’s not documented. If you keep it less than 1-2s  per access token you are clear.
  • Every location, even mountains seem to be categorized as ‘Local business’
  • Currently can not be used outside US and it rarely returns results for locations outside US.
  • Can not be used anonymously, you need the users OAuth access token.
  • Results can be paged

Before Facebook adds proper category info, this API is useful only for finding places by name.

FourSquare v1 API (will be deprecated mid-2011)

Corresponding query from FourSquare v1 API is the ‘venues’ call that is slower but the data quality is much better and denser. You get also category information that is pretty good for filtering and can be used also as human readable description for the venue.

Example query


Example result JSON

{'groups': [{'type': 'Matching Places',
             'venues': [{'address': '85 Rte 17 South',
                        'city': 'East Rutherford',
                        'distance': 1299,
                        'geolat': 40.830497762250729,
                        'geolong': -74.093245267868042,
                        'id': 370040,
                        'name': "CiCi's Pizza Buffet",
                        'phone': '2014388200',
                        'primarycategory': {
                            'fullpathname': 'Food:Pizza',
                            'iconurl': 'http://foursquare.com/img/categories/food/pizza.png',
                            'id': 79081,
                            'nodename': 'Pizza'},
                        'state': 'NJ',
                        'stats': {'herenow': '0'},
                        'verified': False,
                        'zip': '07073'},
                        {'address': '271 Main St.',
                         'city': 'Belleville',
                         'distance': 5168,
                         'geolat': 40.789736300000001,
                         'geolong': -74.146524900000003,
                         'id': 1206994,
                         'name': u'Pizza Village Caf\xe9 II',
                         'phone': '9734501818',
                         'primarycategory': {
                             'fullpathname': 'Food:Pizza',
                             'iconurl': 'http://foursquare.com/img/categories/food/pizza.png',
                             'id': 79081,
                             'nodename': 'Pizza'},
                         'state': 'New Jersey',
                         'stats': {'herenow': '0'},
                         'verified': False,
                         'zip': '07109'},

Data quality is  better than Facebooks and results seem much more relevant, at least for now.

  • Query latency varies a lot
  • Little duplicates, some because of user typos
  • Lots of results also for non-US locations
  • Strict rate limit, you can only do few requests per second and daily total is few hundred. (computed per ip + authenticated user)
  • You should OAuth authenticate your users from Foursquare, otherwise rate limit will make it impossible to use their API.
  • Maximum number of results per query is 50
  • Sometimes returns pretty irrelevant places like homes and such, as category can not be used as query filter

FourSquare v2 API (Beta, work in progress)

v2 API promises improvement over the old v1 and is now available for public use. However it’s still work in progress and there is no guarantee that it stays backwards compatible. Official info here:  http://developer.foursquare.com/docs/overview.html

Unlike v1, v2 does not allow completely anonymous access, so you have to register your application here. Also, only HTTPS is supported. User authentication is OAuth2 that is much simpler to implement than OAuth1 used in v1.

Example (unauthenticated) query.

https://api.foursquare.com/v2/venues/search?client_secret=<<my app secret>>&ll=60.205065%2C24.654196&client_id=<<my app key>>&l=100&llAcc=100

Example response

{'meta': {'code': 200},
 'response': {'groups':
                              [{'icon': 'http://foursquare.com/img/categories/food/pizza.png',
                                'id': '4bf58dd8d48988d1ca941735',
                                'name': 'Pizza',
                                'parents': ['Food'],
                                'primary': True},
                               {'icon': 'http://foursquare.com/img/categories/nightlife/wine.png',
                                'id': '4bf58dd8d48988d123941735',
                                'name': 'Wine Bar',
                                'parents': ['Nightlife']},
                               {'icon': 'http://foursquare.com/img/categories/nightlife/default.png',
                                'id': '4bf58dd8d48988d116941735',
                                'name': 'Bar',
                                'parents': ['Nightlife']}],
                         'contact': {'phone': '4155589991',
                                     'twitter': 'patxispizza'},
                         'hereNow': {'count': 0},
                         'id': '43d7e5dff964a5205d2e1fe3',
                         'location': {'address': '511 Hayes St',
                                      'city': 'San Francisco',
                                      'crossStreet': 'at Octavia Blvd.',
                                      'distance': 474,
                                      'lat': 37.776435900000003,
                                      'lng': -122.425003,
                                      'postalCode': '94102',
                                      'state': 'CA'},
                         'name': "Patxi's Chicago Pizza",
                         'specials': [{'description': 'every check-in',
                                       'id': '4c06d44386ba62b5945588b3',
                                       'message': 'Check-in, show your server, and your first fountain beverage (w/ purchase) is free or your first PBR is only $1. Free 10-inch half-baked pizza of any type, once a week, for the Mayor.',
                                       'type': 'frequency'}],
                         'stats': {'checkinsCount': 2269,
                                   'usersCount': 1115},
                                   'verified': True},

Improvements and changes over v1 API

  • Rate limited as v1
  • Maximum number of results is now over 100
  • Better category structure
  • Venue Twitter handle
  • Address detail includes crossStreet info
  • Specials, etc..

They also changed venue id format from number to hash string, that makes things difficult for those who have already used the old API. I also wish there would be way to filter out private homes from results.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: