API Overview

The Pepper API gives developers access to up-to-date menu and nutrition data from small, local restaurants. Contact us to request access to the API.

Our REST API has resource-oriented URLs and returns JSON responses.

The API has two resources: Restaurants and Dishes. Restaurants contain high-level data such as location and the number of dishes the restaurant has on its menu. Dishes represent an item on a restaurant’s menu, such as a Caesar Salad or Chicken Sandwich. Dishes contain nutritional values, allergens, diets, menu price, the time of day the dish is served, photos, and much more. A single Restaurant object will typically have multiple Dishes.

Endpoints

Restaurant Search returns a list of restaurants.

Restaurant Lookup returns data on a specific restaurant.

Dish Search returns a list of dishes.

Dish Lookup returns nutrition data on a specific dish.

API Reference

Restaurant Search Endpoint

GET https://www.peppersf.com/api/v1/restaurants

Restaurant Lookup Endpoint

GET https://www.peppersf.com/api/v1/restaurants/{restaurant_id}

Dish Search Endpoint

GET https://www.peppersf.com/api/v1/dishes

Dish Lookup Endpoint

GET https://www.peppersf.com/api/v1/dishes/{dish_id}

Authentication

We use private API Keys to authenticate request. You will receive your unique API Key when you sign up. Your API Key should be kept secret! You will have the ability to refresh your API Key to get a new one.

To authenticate API calls with the API Key, set the Authorization HTTP header value as Token <Your API_Key>.

Contact Us to request access to the API

Errors

Pepper uses conventional HTTP response codes to indicate the success or failure of an API request. A 200 code indicates success, while codes in the 5xx range indicate an error on our end. Codes in the 4xx range indicate an error based on the information provided (e.g. a required parameter was omitted).

Handling Errors

200 - OK Everything worked as expected.
400 - Bad Request The parameters were likely incorrect.
401 - Unauthorized Authentication credentials were not provided.
402 - Request Failed The parameters were valid but the request failed.
404 - Not Found The requested resource doesn't exist.
429 - Too Many Requests Too many requests hit the API too quickly.
5xx - Server Errors Something went wrong on Pepper's end.

Restaurant Lookup

Search for a specific restaurant using its restaurant_id. It will return 1 result or raise an error if no restaurant is found.

Request Parameters

restaurant_id Every restaurant has its own unique ID, which you will need to supply to access this endpoint.

Response Attributes

object The type of object in the response. It will either be restaurants or dishes.
restaurant_id The restaurant's own unique ID.
name The name of the restaurant.
cuisine_type The type of cuisine served or a related descriptor for this restaurant.
latitude The latitude of the restaurant.
longitude The longitude of the restaurant.
street_address The street address of the restaurant.
city The city the restaurant is located in.
state The state the restaurant is located in.
zip_code The zip code the restaurant is located in.
country The country the restaurant is located in.
total_dishes The number of dishes at this restaurant for which we have nutrition data.
dairy_free_dishes The number of dairy-free dishes served at this restaurant.
egg_free_dishes The number of egg-free dishes served at this restaurant.
fish_free_dishes The number of fish-free dishes served at this restaurant.
shellfish_free_dishes The number of shellfish-free dishes served at this restaurant.
mollusk_free_dishes The number of mollusk-free dishes served at this restaurant.
crustacean_free_dishes The number of crustacean-free dishes served at this restaurant.
soy_free_dishes The number of soy-free dishes served at this restaurant.
sesame_free_dishes The number of sesame-free dishes served at this restaurant.
peanut_free_dishes The number of peanut-free dishes served at this restaurant.
tree_nut_free_dishes The number of tree nut-free dishes served at this restaurant.
gluten_free_dishes The number of gluten-free dishes served at this restaurant.
wheat_free_dishes The number of wheat-free dishes served at this restaurant.
vegan_dishes The number of vegan dishes served at this restaurant.
pescatarian_dishes The number of pescatarian dishes served at this restaurant.
paleo_dishes The number of paleo dishes served at this restaurant.
vegetarian_dishes The number of vegetarian dishes served at this restaurant.
kosher_dishes The number of kosher dishes served at this restaurant.
red_meat_free_dishes The number of red meat-free dishes served at this restaurant.
pork_free_dishes The number of pork-free dishes served at this restaurant.
low_fructose_dishes The number of low fructose dishes served at this restaurant.
low_lactose_dishes The number of low lactose dishes served at this restaurant.
low_mannitol_dishes The number of low mannitol dishes served at this restaurant.
low_sorbitol_dishes The number of low sorbitol dishes served at this restaurant.
low_gos_dishes The number of low gos dishes served at this restaurant.
low_fructan_dishes The number of low fructan dishes served at this restaurant.

Example Requests

curl -X GET https://www.peppersf.com/api/v1/restaurants/r_bmneRtIbX5s1FvqrH3/ -H 'Authorization: Token <Your API_Key>'
require 'net/http'
require 'json'

uri = URI('https://www.peppersf.com/api/v1/restaurants/')
params = { "name" => "poki time" }
uri.query = URI.encode_www_form(params)
req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Token <Your API_Key>"
response = Net::HTTP.start(uri.hostname, uri.port,
            :use_ssl => uri.scheme == 'https') {|http| http.request(req)}
example_response = JSON.parse(response.body)
import requests
import json

u = 'https://www.peppersf.com/api/v1/restaurants/'
p = {'name': 'poki time'}
h = {'Authorization': 'Token <Your API_Key>'}
r = requests.get(u, params=p, headers=h)
example_response = r.json()
package com.mkyong;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class PepperAPI {

    public static void main(String[] args) throws Exception {
        PepperAPI http = new PepperAPI();
        http.sendGet();
    }

    private void sendGet() throws Exception {
        String url = "https://www.peppersf.com/api/v1/restaurants/?name=poki+time";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestProperty("Authorization", "Token <Your API_Key>");
        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer example_response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            example_response.append(inputLine);
        }
        in.close();
    }

}
const request = require('request');

const options = {
  url: 'https://www.peppersf.com/api/v1/restaurants/',
  headers: {
    'Authorization': 'Token <Your API_Key>'
  },
  qs: {name: 'poki time'}
};

function callback(error, response, body) {
    const example_request = JSON.parse(body);
}

request(options, callback);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    req, err := http.NewRequest("GET", "https://www.peppersf.com/api/v1/restaurants/", nil)
    req.Header.Add("Authorization","Token <Your API_Key>")
    if err != nil {
        fmt.Println(err)
    }
    q := req.URL.Query()
    q.Add("name", "poki time")
    req.URL.RawQuery = q.Encode()
    client := &http.Client{}
    resp, err := client.Do(req)
    example_response, _ := ioutil.ReadAll(resp.Body)
}

Example Response

{
  "object":"restaurants",
  "data":[
    {
      "restaurant_id":"r_6LAeju6Ku6eJhIxQLq",
      "name":"Bravado",
      "cuisine_type":"Cafe",
      "latitude":37.778761,
      "longitude":-122.391351,
      "location":{
        "street_address":"170 King St",
        "city":"San Francisco",
        "state":"California",
        "zip_code":"94107",
        "country":"United States"
      },
      "dish_counts":{
        "total_dishes":15,
        "dairy_free_dishes":2,
        "egg_free_dishes":8,
        "fish_free_dishes":15,
        "shellfish_free_dishes":14,
        "mollusk_free_dishes":14,
        "crustacean_free_dishes":15,
        "soy_free_dishes":15,
        "sesame_free_dishes":14,
        "peanut_free_dishes":15,
        "tree_nut_free_dishes":11,
        "gluten_free_dishes":2,
        "wheat_free_dishes":2,
        "vegan_dishes":1,
        "pescatarian_dishes":7,
        "paleo_dishes":0,
        "vegetarian_dishes":6,
        "kosher_dishes":10,
        "red_meat_free_dishes":10,
        "pork_free_dishes":11,
        "low_fructose_dishes":3,
        "low_lactose_dishes":13,
        "low_mannitol_dishes":6,
        "low_sorbitol_dishes":8,
        "low_gos_dishes":8,
        "low_fructan_dishes":1
      }
    }
  ]
}

Dish Lookup

Search for a specific dish using its dish_id. It will return 1 result or raise an error if no dish is found.

Request Parameters

dish_id Every dish has its own unique ID, which you will need to supply to access this endpoint.

Response Attributes

object The type of object in the response. It will either be restaurants or dishes.
dish_id The dish's own unique ID.
restaurant_id The unique ID of the restaurant that makes this dish.
restaurant_name The name of the restaurant that makes this dish.
name Name of the dish as listed on the menu.
price Price of the dish as listed on the menu (in USD).
menu_serving_time A list with the times of day that the dish is served. Choices are Breakfast, Brunch, Lunch and Dinner.
serving_size_colloquial An informal unit of measurement for the dish.
serving_size_weight Weight of the dish (in grams).
image When available, a URL image of the dish. All images are 150x150 pixels.
low_sodium Whether or not the dish is low in sodium (boolean).
low_carb Whether or not the dish is low in carbohydrates (boolean).
low_fat Whether or not the dish is low in fat (boolean).
high_fiber Whether or not the dish is high in fiber (boolean).
high_protein Whether or not the dish is high in protein (boolean).
dairy_free Whether or not the dish is dairy free (boolean).
egg_free Whether or not the dish is egg free (boolean).
fish_free Whether or not the dish is fish free (boolean).
gluten_free Whether or not the dish is gluten free (boolean).
peanut_free Whether or not the dish is peanut free (boolean).
sesame_free Whether or not the dish is sesame free (boolean).
shellfish_free Whether or not the dish is shellfish free (boolean).
mollusk_free Whether or not the dish is mollusk free (boolean).
crustacean_free Whether or not the dish is crustacean free (boolean).
soy_free Whether or not the dish is soy free (boolean).
tree_nut_free Whether or not the dish is tree_nut free (boolean).
wheat_free Whether or not the dish is wheat free (boolean).
vegan Whether or not the dish is vegan (boolean).
pescatarian Whether or not the dish is pescatarian (boolean).
paleo Whether or not the dish is paleo (boolean).
vegetarian Whether or not the dish is vegetarian (boolean).
kosher Whether or not the dish is kosher (boolean).
red_meat_free Whether or not the dish is free of red meat (boolean).
pork_free Whether or not the dish is free of pork (boolean).
fructose FODMAP rating for the amount of fructose in the dish. The dish can be Low, Medium, or High in fructose. View the FODMAP section to learn how we calculate these values.
lactose FODMAP rating for the amount of lactose in the dish. The dish can be Low, Medium, or High in lactose. View the FODMAP section to learn how we calculate these values.
mannitol FODMAP rating for the amount of mannitol in the dish. The dish can be Low, Medium, or High in mannitol. View the FODMAP section to learn how we calculate these values.
sorbitol FODMAP rating for the amount of sorbitol in the dish. The dish can be Low, Medium, or High in sorbitol. View the FODMAP section to learn how we calculate these values.
gos FODMAP rating for the amount of gos in the dish. The dish can be Low, Medium, or High in gos. View the FODMAP section to learn how we calculate these values.
fructane FODMAP rating for the amount of fructane in the dish. The dish can be Low, Medium, or High in fructane. View the FODMAP section to learn how we calculate these values.
calories Number of calories in the dish (in kcal).
total_fat Amount of total fat in the dish (in grams).
saturated_fat Amount of saturated fat in the dish (in grams).
monounsaturated_fat Amount of monounsaturated fat in the dish (in grams).
polyunsaturated_fat Amount of polyunsaturated fat in the dish (in grams).
trans_fat Amount of trans fat in the dish (in grams).
carbohydrates Amount of carbohydrates in the dish (in grams).
sugars Amount of sugars in the dish (in grams).
protein Amount of protein in the dish (in grams).
cholesterol Amount of cholesterol in the dish (in milligrams).
sodium Amount of sodium in the dish (in milligrams).
calcium Amount of calcium in the dish (in milligrams).
magnesium Amount of magnesium in the dish (in milligrams).
potassium Amount of potassium in the dish (in milligrams).
iron Amount of iron in the dish (in milligrams).
zinc Amount of zinc in the dish (in milligrams).
phosphorus Amount of phosphorus in the dish (in milligrams).
vitamin_a Amount of vitamin a in the dish (in micrograms).
vitamin_c Amount of vitamin c in the dish (in milligrams).
thiamin_b1 Amount of thiamin b1 in the dish (in milligrams).
riboflavin_b2 Amount of riboflavin b2 in the dish (in milligrams).
niacin_b3 Amount of niacin b3 in the dish (in milligrams).
vitamin_b6 Amount of vitamin b6 in the dish (in milligrams).
folate Amount of folate in the dish (in micrograms).
vitamin_e Amount of vitamin e in the dish (in milligrams).
vitamin_k Amount of vitamin k in the dish (in micrograms).
fiber Amount of fiber in the dish (in grams).
folic_acid Amount of folic acid in the dish (in micrograms).
vitamin_b12 Amount of vitamin b12 in the dish (in micrograms).
vitamin_d Amount of vitamin d in the dish (in micrograms).
options List of all of the dish's associated options. Each option includes the same health labels, allergies, diets, FODMAPs, and nutrients as the dish. View the Options section to learn more.

Example Requests

curl -X GET https://www.peppersf.com/api/v1/dishes/d_XfNiqGULpPaTgX8R6r/ -H 'Authorization: Token <Your API_Key>'
require 'net/http'
require 'json'

u = URI('https://www.peppersf.com/api/v1/dishes/d_XfNiqGULpPaTgX8R6r/')
req = Net::HTTP::Get.new(u)
req['Authorization'] = "Token <Your API_Key>"
r = Net::HTTP.start(u.hostname, u.port,
            :use_ssl => u.scheme == 'https') {|http| http.request(req)}
example_response = JSON.parse(r.body)
import requests
import json

u = 'https://www.peppersf.com/api/v1/dishes/d_XfNiqGULpPaTgX8R6r'
h = {'Authorization': 'Token <Your API_Key>'}
r = requests.get(u, headers=h)
example_response = r.json()
package com.mkyong;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class PepperAPI {

    public static void main(String[] args) throws Exception {
        PepperAPI http = new PepperAPI();
        http.sendGet();
    }

    private void sendGet() throws Exception {
        String u = "https://www.peppersf.com/api/v1/dishes/d_XfNiqGULpPaTgX8R6r";
        URL obj = new URL(u);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestProperty("Authorization", "Token <Your API_Key>");
        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer example_response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            example_response.append(inputLine);
        }
        in.close();
    }

}
const request = require('request');

const options = {
  url: 'https://www.peppersf.com/api/v1/dishes/d_XfNiqGULpPaTgX8R6r/',
  headers: {
    'Authorization': 'Token <Your API_Key>'
  }
};

function callback(error, response, body) {
    const example_request = JSON.parse(body);
}

request(options, callback);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    req, err := http.NewRequest("GET", "https://www.peppersf.com/api/v1/dishes/d_XfNiqGULpPaTgX8R6r", nil)
    req.Header.Add("Authorization","Token <Your API_Key>")
    if err != nil {
        fmt.Println(err)
    }
    client := &http.Client{}
    resp, err := client.Do(req)
    example_response, _ := ioutil.ReadAll(resp.Body)
}

Example Response

{
  "object":"dishes",
  "data":[
    {
      "dish_id":"d_XfNiqGULpPaTgX8R6r",
      "restaurant_id ":"r_Oiqw3tKNBoXX4iBVr6",
      "restaurant_name ":"Rambler",
      "name":"Cobb Salad",
      "price":14.0,
      "menu_serving_time":[
        "Lunch"
      ],
      "serving_size_colloquial":"1 order",
      "serving_size_weight":480.7,
      "image":"None",
      "base":{
        "health_labels":{
          "low_sodium":false,
          "low_carb":false,
          "low_fat":false,
          "high_fiber":false,
          "high_protein":false
        },
        "allergies":{
          "dairy_free":false,
          "egg_free":false,
          "fish_free":true,
          "gluten_free":true,
          "peanut_free":true,
          "sesame_free":true,
          "shellfish_free":true,
          "mollusk_free":true,
          "crustacean_free":true,
          "soy_free":true,
          "tree_nut_free":true,
          "wheat_free":true
        },
        "diets":{
          "vegan":false,
          "pescatarian":false,
          "paleo":false,
          "vegetarian":false,
          "kosher":false,
          "red_meat_free":false,
          "pork_free":false
        },
        "fodmaps":{
          "fructose":"Low",
          "lactose":"Low",
          "mannitol":"Low",
          "sorbitol":"High",
          "gos":"Low",
          "fructan":"Low"
        },
        "nutrition":{
          "calories":691.7,
          "total_fat":58.3,
          "saturated_fat":21.6,
          "monounsaturated_fat":25.8,
          "polyunsaturated_fat":6.7,
          "trans_fat":0.1,
          "carbohydrates":17.1,
          "sugars":5.1,
          "protein":29.1,
          "cholesterol":229.1,
          "sodium":1093.1,
          "calcium":399.5,
          "magnesium":81.3,
          "potassium":1334.4,
          "iron":3.7,
          "zinc":3.7,
          "phosphorus":491.9,
          "vitamin_a":491.3,
          "vitamin_c":24.1,
          "thiamin_b1":0.4,
          "riboflavin_b2":0.7,
          "niacin_b3":5.6,
          "vitamin_b6":0.7,
          "folate":252.1,
          "vitamin_e":3.5,
          "vitamin_k":201.1,
          "fiber":9.3,
          "folic_acid":0.0,
          "vitamin_b12":1.4,
          "vitamin_d":1.4
        }
      },
      "options":{
        "option_count":3,
        "group_count":2,
        "2":{
          "Add Shrimp":{
            "health_labels":{...},
            "allergies":{...},
            "diets":{...},
            "fodmaps":{...},
            "nutrition":{...}
          },
          "Add Grilled Chicken":{
            "health_labels":{...},
            "allergies":{...},
            "diets":{...},
            "fodmaps":{...},
            "nutrition":{...}
          },
        },
        "1":{
          "Add Blue Cheese Dressing":{
            "health_labels":{...},
            "allergies":{...},
            "diets":{...},
            "fodmaps":{...},
            "nutrition":{...}
          },
        }
      }
    }
  ]
}

Options

Options represent choice as reflected on the menu. Choices can include choosing a main meat (e.g. chicken or beef), a side (e.g. green beans), an add-on (e.g. avocado), or even a size (e.g. small vs large). Each option contains its own, stand-alone nutritional values for that Option. You will need to add, subtract, and adjust the base dish as necessariy to reflect changes in the overall dish.

Options are grouped together in dictionaries to reflect how they are presented on the menu. For example, at Torraku Ramen, a customer can choose between chashu and kakuni for meat, and then can add garlic and/or spicey sauce. The cashu and kakuni are grouped together in one dictionary, while the garlic and spicey sauce are grouped together in another. Options are typically grouped in the order that they appear on the menu, so the meats in our example are in group/dictionary 1 while the sauces are in group/dictionary 2.

FODMAPs

To determine FODMAPs for a Dish, we first calculate values for each individual ingredient in the Dish. Ingredient values are then aggregated to assign a Low, Medium, or High classification for each FODMAP to the overall Dish. We do the same thing for Options.

For example, let's say a Salad has Lettuce, Tomato, and Carrots as ingredients. It also has an Option for Dressing. The Lettuce, Tomato, and Carrots are Low in every type of FODMAP. The dressing is High in Fructan, but Low in all the other FODMAPs. The Salad (Dish) will be assigned a Low value for each FODMAP. The Dressing (Option) will be assigned a High value for Fructan and a Low value for the other FODMAPs.