API Documentation

Overview

Spots

On the Foodspotting website and iPhone app when you add a new entry into the system, it is often referred to as a "spot" or "spotting". But in the underlying system this concept is actually made up of two objects, sightings and reviews. When you spot a new food at a place, what you create is actually a review, which gets associated with a sighting, so it is important to understand the different roles these objects play.

A sighting is a simple container that associates an item (food) with a place (restaurant, bar, etc). Whereas a review is what a user creates when they "spot" a food by uploading a picture and an optional note. When a review is created it is either added to an existing sighting if the food has already been spotted at this restaurant before, otherwise a new sighting is automatically created.

So when you want to search for good foods in your area, you search for sightings, then dig into the sightings you find to see the individual reviews, which contain the photos and comments from users.

Format, responses and errors

URL format

The Foodspotting API is based on RESTful principles and the basic URL format looks like this:

  http://www.foodspotting.com/api/vVERSION/RESOURCE.json?api_key=API_KEY

VERSION specifies the version of the call. Currently the only supported version is 1.

RESOURCE is the specific resource that you want to access. E.g. items or people/kimtaro/reviews.

API_KEY is required for all requests made to the API. Register your application to get your key.

Response format

The only output format currently supported by the API is JSON. Specifying any other format will result in a 406 Not Acceptable response.

All API responses come in a standardized JSON format with three sections: meta, data and pagination.

meta

This section contains information about the call, such as its success status, HTTP code and any errors that might have occurred. All calls will have at least a code and success key in this section.

data

This section contains the actual meat of the response. It will always be a hash, and unless otherwise noted in the list of calls below, will have at least one key correspoding to the resource you asked for. If you requested a single object, for example /item.json, the key would be item and its value would be that item. If you requested several objects, for example /items.json, the key would be items and its value would be an array with the items. The format of each object in the Foodspotting world is described in the Objects section.

pagination

For resources that can return multiple objects, signified by a plural name in the URL, this section gives you information on how many objects are available and how many you are getting in this request. total_entries tells you how many objects there are in total for the request you made. total_pages how many pages there are in total with the current per_page setting, which tells you how many objects you will see in each request. current_page tells you which page you are on in this request.

You can specify which, and how many, objects you want by setting the page and per_page parameters in your request.

Example response

  { "meta": { "success": true, "code": 200 }, "data": { "items": [{ "name": "Morning Buns", "id": 1 }, ... ] }, "pagination": { "current_page": 1, "per_page": 10, "total_pages": 9262, "total_entries": 92614 } }

JSONP

We support JSONP when there is a callback parameter specified to allow for cross domain requests.

Errors

When an error occurs we will respond with the proper HTTP code, depending on the error, and an error explanation in the meta section of the JSON response. The data and meta sections will be empty hashes. Here's an example of the meta section in case of an error.

  { "errors": ["Name is required"], "code": 400, "success": false }

success will always be false for errors. code reflects the HTTP status code for the error. errors is an array with further details about the error. For example when you create an object and forget a required parameter this might contain something like "Name is required".

When you make a JSONP request the return code will always be 200, and you should inspect the success parameter in the meta part of the JSON response. If it is false then the request failed and you can inspect the errors and code attributes for more information.

Pagination

For resources that can return multiple objects (signified by a plural object name in the URL) you can in most cases specify how many and wich objects you want with the page and per_page parameters. For example, this URL http://www.foodspotting.com/api/v1/items.json?page=5&per_page=3 will return this:

  { "items": [{ "name": "Basteeya", "id": 14 }, { "name": "Scallop Curry", "id": 15 }, { "name": "Teriyaki Steak Bowl", "id": 17 }], "total_entries": 92614, "total_pages": 30872, "per_page": 3, "current_page": 5 }

total_entries tells you how many objects there are in total for the request you made. total_pages how many pages there are in total with the current per_page setting, which tells you how many objects you will see in each request. current_page tells you which page you are on in this request.

Authentication

The Foodspotting API currently supports OAuth 1.0 and OAuth 2 draft 10 for authentication. This means that if you want to access resources on the behalf of a Foodspotting user you have to do so by authenticating with either of these methods.

The API key and secret needed for the authentication process for your application is available on your application's detail page. To see your applications, use the applications and tokens page.

OAuth 1.0

You can read more about OAuth 1.0 and how it works on oauth.net. They also host a good list of libraries for easily using it in many different languages.

Please use hmac-sha1 to sign your requests when using OAuth 1.0.

Request Token URL   http://www.foodspotting.com/oauth/request_token

Authorize URL   http://www.foodspotting.com/oauth/authorize

Access Token URL   http://www.foodspotting.com/oauth/access_token

OAuth 2

We support a subset of draft 10 of the OAuth 2 specification. Specifically the Web Server and User-Agent client profiles, using Authorization Code access grant to obtain an access token.

Please note that the OAuth2 specification is still in active development, and that we reserve the right to update our implementation to conform to newer drafts as they are released. This might break backwards compatibility with applications using older drafts.

Authorization code URL   https://www.foodspotting.com/oauth/authorize

Access token URL   https://www.foodspotting.com/oauth/token

Obtaining an access token

To obtain an access token and user authorization you must first redirect the user to the following URL.

URL
https://www.foodspotting.com/oauth/authorize
METHOD
GET

PARAMS

Param Value
response_type code, token
client_id Your app's api key
redirect_uri The registered redirect_uri for your app

This will present the user with the option to grant access to their account for your application, or deny it. Once the user has made their choice they will be redirected to your redirect_uri. If they granted access and the response_type is code then the user will be redirected to this:   REDIRECT_URI?code=AUTHORIZATION_CODE

If the response_type is token then the redirect will be to:   REDIRECT_URI#access_token=ACCESS_TOKEN

If the user denied access the redirect_uri will have this appended to the query string.   error=user_denied

Once you have the authorization code you can obtain the access token by making the following call.

URL
https://www.foodspotting.com/oauth/token
METHOD
POST

PARAMS

Param Value
grant_type authorization_code
client_id Your app's api key
client_secret Your app's secret key
code The authorization code you obtained
redirect_uri The registered redirect_uri for your app

RESPONSE

  {"access_token":"ACCESS_TOKEN"}

Making authenticated calls

To make an authenticated call to the API using an OAuth2 access token, you can either set the oauth_token parameter to your access token, or set the Authorization header to OAuth ACCESS_TOKEN. Please note that these methods are also subject to change as we update our implementation to newer versions of the OAuth 2 specification.

Register your application to get your consumer key and secret.

Uploading images

Every review in Foodspotting must have an image attached. To upload an image when creating a review with the review creation call you need to construct a Content-Type multipart/form-data request. The raw data of the image is inserted in the review["photo"] parameter.

Here is an example review creation call with an image in multipart/form-data format:

Header

  Content-Type: multipart/form-data; boundary=AaB03x

Body

  --AaB03x Content-Disposition: form-data; name="review[photo]"; filename="food.jpg" Content-Type: image/jpeg /.../ Raw JPEG data goes here /.../ --AaB03x Content-Disposition: form-data; name="item[name]" Scrumptious Bacon --AaB03x Content-Disposition: form-data; name="place[id]" 1 --AaB03x--

Example code

We have prepared a sample project in Ruby to show how to easily access both resources that doesn't require authentication and resources that do. The project is a small Sinatra application and uses a few very common gems to handle authentication and API communication.

The sample application contains working examples of both OAuth 1.0 and OAuth 2 authentication.

Get the code from GitHub

  git clone git@github.com:Foodspotting/spotter-app.git

Objects in the Foodspotting world

Items

A dish or food item. (e.g. Eggs, Eggs Benedict)

JSON Format

  { "name": "Morning Buns", "id": 1 }

Places

A place to find an item. (e.g. Tim's Vegan Shakes, Tokyo Farmers Market)

JSON Format

  • "following" will be present and true or false if the authenticated user is following the place.
  • "distance" will be present if the "longitude" and "latitude" parameters are present and will indicate the distance in miles from the point to the place.
  { "id": 3, "name": "Dosa", "phone_number": "(415) 642-3672", "street_address": "995 Valencia St", "street_address_2": "", "city": "San Francisco", "state": "CA", "country": "", "postal_code": "", "latitude": 37.757119, "longitude": -122.421011, "followings_count": 6, "sightings_count": 29, "foursquare_id": "439b6598f964a520e12b1fe3", "following": true, "distance": 0 }

Sightings Authentication optional

A container object for an item at a place.

JSON Format

  • "nommed" and "wanted" is normally "null". But when the request is authenticated these will be booleans indicating if the authenticated user wants or has nommed this sighting.
  • The "creator_id" holds the person id of the person who created the sighting. This is either the first person to review the item at this place, or the first person to add this item to this place in a guide.
  • "current_review" contains the latest review of this sighting. If the sighting has no reviews this object will be "null".
  { "place": {Place JSON}, "reviews_count": 51, "updated_at": "2010-10-26T22:44:17Z", "latitude": 37.7615436, "created_at": "2009-09-30T23:03:50Z", "item": {Item JSON}, "wanted": null, "creator_id": 9, "longitude": -122.4238768, "current_review": {Review JSON}, "distance": null, "nommed": null, "last_review_at": "2010-10-26T22:43:55Z", "id": 1, "wants_count": 80, "ribbons_count": 63 }

Reviews

An individual instance of a spotting uploaded by a user, contains the photo and note.

JSON Format

  • "nommed" and "wanted" are booleans indicating if the person who created the review wants or nommed the item at this place.
  • The "shared_to" object is available for newly created reviews and indicates which service the review was shared to based on the sharing settings in the Create Review call.
  { "place": {Place JSON}, "comments_count": 2, "thumb_120": "http://s3.amazonaws.com/foodspotting-development-ec2/reviews/1/thumb_120.jpg?1254351830", "nommed": true, "person_id": 9, "updated_at": "2010-10-30T20:32:40Z", "great_finds_count": 0, "created_at": "2009-09-30T23:03:53Z", "taken_at": "2009-09-30T23:03:53Z", "note": "I am not usually a croissant dough person, but these are amazing. The citrus glaze makes the top sticky and chewy. Eating these on the top of Dolores Park is an experience not to miss!", "item": {Item JSON}, "thumb_280": "http://s3.amazonaws.com/foodspotting-development-ec2/reviews/1/thumb_275.jpg?1254351830", "great_shots_count": 2, "person": {Person JSON}, "thumb_90": "http://s3.amazonaws.com/foodspotting-development-ec2/reviews/1/thumb_90.jpg?1254351830", "thumb_170": "http://s3.amazonaws.com/foodspotting-development-ec2/reviews/1/thumb_170.jpg?1254351830", "id": 1, "wanted": true, "sighting_id": 1, "shared_to": { "facebook": false, "flickr": false, "foursquare": false, "twitter": false } }

Comments

A comment by a person on a review.

JSON Format

  { "created_at": "2010-10-26T19:53:45Z", "text": "Wow, thanks for the correction. I'm so absentminded sometimes! Of course it's Dolores Park. Fixed!", "person": {Person JSON}, "id": 10681 }

Guides

A collection of sightings.

JSON Format

  • "guide_sightings" are the sightings that belong to this guide.
  • If authenticated, then "membership" will contain information about the authenticated user's status in the guide if he/she has joined it. It's a JSON object with these attributes: "joined_at", "completed_at" and "reviewed_sightings_count".
  • If authenticated, then "review" in"guide_sightings" will contain the authenticated user's review for this sighting in this guide.
  { "tagline": null, "membership": null, "latitude": 37.7141, "sightings_count": 11, "formatted_description": "

Our favorite weekend pastime! Eat your way up and down the Bay.

", "city": "Bay Area", "created_at": "2010-01-22T02:25:21Z", "guide_sightings": [{ "comment": null, "sighting": {Sighting JSON}, "review": null, "guide_sighting_votes_count": 1, "id": 366 } ...], "participants_count": 20, "longitude": -122.25, "contributors_count": 0, "person": {Person JSON}, "thumb_90": "http://s3.amazonaws.com/foodspotting-development-ec2/guides/9/thumb.png?1265010732", "description": "Our favorite weekend pastime! Eat your way up and down the Bay.", "title": "Progressive Snacking", "id": 9, "thumb_50": "http://s3.amazonaws.com/foodspotting-development-ec2/guides/9/small_thumb.png?1265010732" }

People

A Foodspotting user.

JSON Format

  • When retrieving data about the logged in user through the Current Person call, the "sharing_available_for" object will tell you which services the user has enabled for sharing their reviews to.
  { "location": "Tokyo", "reviews_count": 152, "guides_count": 6, "tips_count": 9295, "recent_notifications_count": 0, "noms_count": 13, "notifications_count": 241, "avatar": "http://s3.amazonaws.com/foodspotting-development-ec2/people/10/small_thumb.jpg?1254810254", "followings_count": 31, "name": "Kim Ahlstr\u00f6m", "id": 10, "wants_count": 214, "sharing_available_for": { facebook: false, flickr: false, foursquare: false, twitter: false } }

Calls

These are all the calls currently available in the Foodspotting API.

Required parameters

Items

List and search

URL
http://www.foodspotting.com/api/v1/items.json
METHOD
GET
Param Type Options
query String
per_page Integer
page Integer

Places

List and search

URL
http://www.foodspotting.com/api/v1/places.json
METHOD
GET

This parameter only applies when neither query or longitude and latitude is set.

Param Type Options
query String
show String mappable.
latitude Float
longitude Float
per_page Integer
page Integer

Sightings

List and search Authentication optional

URL
http://www.foodspotting.com/api/v1/sightings.json
METHOD
GET
Param Type Options
query String
latitude Float
longitude Float
sort String latest, nearest, best, wanted
filter String all, wanted, following.

Wanted and following only work when the call is made authenticated.

within Float (in miles)
page Integer
per_page Integer
item_id Integer
place_id Integer

Reviews

Gives you the reviews associated with a sighting.

URL
http://www.foodspotting.com/api/v1/sightings/:sighting-id/reviews.json
METHOD
GET

Want Authentication required

Allows you to want the sighting for the authenticated person. This toggles the want status for this user, and the 'created' value in the response will tell you if this created or removed the want.

URL
http://www.foodspotting.com/api/v1/sightings/:sighting-id/want.json
METHOD
POST
Param Type Options
review_id Integer Allows you to optionally associate the want with a specific review

RESPONSE JSON

  { "created": Boolean, }

Nom Authentication required

Allows you to nom the sighting for the authenticated person. This toggles the nom status for this user, and the 'created' value in the response will tell you if this created or removed the nom.

URL
http://www.foodspotting.com/api/v1/sightings/:sighting-id/nom.json
METHOD
POST
Param Type Options
review_id Integer Allows you to optionally associate the nom with a specific review

RESPONSE JSON

The response may contain an optional 'errors' key, with the value ['No ribbons left'] when the created value is false. This indicates that the user has no more noms left to give. The user must earn more points or remove an exising nom before he or she can nom again.

  { "created": Boolean, }

Reviews

List

URL
http://www.foodspotting.com/sightings/[sighting-id]/reviews.json
METHOD
GET
PARAMS
Param Type Options
page Integer
per_page Integer

Create Authentication required

URL
http://www.foodspotting.com/api/v1/reviews.json
METHOD
POST

See the documentation on how to upload an image for information on how to attach an image with your review.

REVIEW PARAMS

Param Type Options
review[photo] JPEG, PNG, GIF
review[note] String
review[nom] Boolean Set this to true to nom the review.

PLACE PARAMS
A new place will be created unless the name, latitude & longitude match an existing record.

Param Type Options
place[name] String
place[street_address] String
place[city] String
place[state] String
place[country] String
place[phone_number] String
place[google_id] String

ITEM PARAMS
A new item will be created unless name or id match an existing record.

Param Type Options
item[name] String
item[id] Integer

SHARING PARAMS
These parameters control which services the review should be shared to. The user must first have enabled the service in their account settings. To see which services the user has enabled, check the "sharing_available_for" object in the Current Person call.

Param Type Options
share_to[facebook] Boolean
share_to[foursquare] Boolean
share_to[flickr] Boolean
share_to[twitter] Boolean

Flag Authentication required

URL
http://www.foodspotting.com/api/v1/reviews/:id/flag.json
METHOD
POST

PARAMS

Param Type Options
flag[description] String

RESPONSE JSON

  { "flag": { "name": String, "description": String } }

Great Shot Authentication required

URL
http://www.foodspotting.com/api/v1/reviews/:id/great_shot.json
METHOD
POST

PARAMS

Param Type Options

RESPONSE JSON

  { "great_shot": { "created": Boolean, "great_shots_count": Integer } }

Great Find Authentication required

URL
http://www.foodspotting.com/api/v1/reviews/:id/great_find.json
METHOD
POST

PARAMS

Param Type Options

RESPONSE JSON

  { "great_find": { "created": Boolean, "great_finds_count": Integer } }

Review Comments

Create Authentication required

URL
http://www.foodspotting.com/api/v1/reviews/:review-id/comments.json
METHOD
POST
Param Type Options
comment[text] String

Guides

List and search Authentication optional

URL
http://www.foodspotting.com/api/v1/guides.json
METHOD
GET
Param Type Options
latitude Float
longitude Float
sort String created_at, featured, participants
filter String all, featured, following.

Following only works when the call is made authenticated.

page Integer
per_page Integer

Join Authentication required

This call joins the authenticated user in the specified guide.

URL
http://www.foodspotting.com/api/v1/guides/:guide-id.json
METHOD
POST

RESPONSE JSON

  { "joined": Boolean, "guide_membership": { "joined_at": DateTime, "completed_at": DateTime, "reviewed_sightings_count": Integer } }

People

Note that anywhere where a person-id is required you can also instead use the person's screen name if they have one set.

Current Authentication required

This will show person data for the authenticated person.

URL
http://www.foodspotting.com/api/v1/people/current.json
METHOD
GET

Reviews

This call will give you all the reviews created by the specified person.

URL
http://www.foodspotting.com/api/v1/people/:person-id/reviews.json
METHOD
GET
Param Type Options
per_page Integer
page Integer
sort String latest, nearest
latitude Float
longitude Float

Wants

This call will give you all the sightings wanted by the specified person.

URL
http://www.foodspotting.com/api/v1/people/:person-id/wants.json
METHOD
GET
Param Type Options
per_page Integer
page Integer
sort String latest, nearest
latitude Float
longitude Float

Guides

This call will give you all the guides created by the specified person.

URL
http://www.foodspotting.com/api/v1/people/:person-id/guides.json
METHOD
GET
Param Type Options
per_page Integer
page Integer