Overview
Introduction
The delivery.com Developer API provides all of the tools, functionality, and data to interact with the delivery.com ecosystem in new and creative ways.
The fundamental capabilities allow users to:
- Search for local restaurants, liquor stores, and laundries that offer delivery and pickup.
- Make purchases through the checkout API.
As you can see in the Table of Contents to the left, Food and Liquor orders require a separate API from Laundry and Dry Cleaning orders, which you can learn more about in the API Overview for each.
Why dive in?
With the first open API of its kind, delivery.com offers the unique opportunity for developers to generate real revenue by leveraging our network of more than 10,000 businesses in major cities across the country.
Ongoing revenue share: Earn 25% of net revenue on every order that originates from an app that you create.
Ready to get started? Sign up now.
Rules and Best Practices
In order to protect the delivery.com ecosystem, you must adhere to the following rules and best practices. Failure to do so will result in the revocation of your API key.
- Never ask users for their delivery.com account credentials or credit card information. We support OAuth 2.0 authentication. When adding credit cards, we have a similar flow to OAuth 2.0. See more in the Authentication and Payment sections.
- Do not store or cache our data. This will certainly lead to bugs, as data tends to change frequently, and it also violates our terms of service. If you think a particular endpoint is too slow, please let us know and we’ll do our best to improve it.
- In the instance of alcohol or tobacco sales, certain guidelines must be followed. See the Legal Disclaimers section for more information.
- Adhere to our branding and attribution requirements.
- To prevent your transactions from being incorrectly flagged as fraudulent, you must send the customer’s actual data. Examples include, but are not limited to:
- The customer’s actual credit card data. Don’t use one card for all of your users.
- IP address. (Please specify the true client IP in http header “HTTP_X_FORWARDED_FOR“.)
- Email address.
- First and last name.
- Phone number. For more detailed DO’s and DON’Ts (along with a healthy dose of legalese) please see our Terms of Service.
Sign Up
If you’d like to use the API, please send an email to “api (at) delivery (dot) com”. Please include the following details:
- Name
- Company (if applicable)
- Company Size (if applicable)
- What you’re planning to build
- Any other useful or interesting information
Please note: It’s been great to see interest in our API coming from all over the world, but right now we’re only pursuing projects inside the United States. Once you have your API key, you can manage your API account by logging into admin.delivery.com.
Branding Requirements
Please see the latest branding and attribution requirements here
Getting Started
API Overview
Authentication Basics
Before jumping in, it is important to cover the three basic levels of Authentication that delivery.com supports:
Level | Authentication | Description |
---|---|---|
Unauthenticated | client_id | Used for most GET calls such as merchant information, menu items, and general search. |
Password Flow | oauth token | Any POST calls and customer specific calls that require prior authorization. |
Trusted Flow | oauth token | Any calls with credit cards. |
Unauthenticated
When you sign up for a new API account, you will immediately be able to make “unauthenticated” calls. Simply append your client_id to the request as such:
https://api.delivery.com/endpoint/?client_id={client_id}
To learn more about Password Flow or Trusted Flow please check out the more detailed Authentication section.
Making Requests
- All unauthenticated API requests (requests without an Authorization header) must include a client_id parameter. You receive a client_id by signing up.
- All production requests must use SSL.
- All authenticated API requests must include an access token in the Authorization HTTP header. See Authentication.
Environment | URL | client_id |
---|---|---|
Production | https://api.delivery.com | Your app’s client_id. |
Development | Sandbox accounts has been deprecated as of 5/17/2016 |
Here’s an example of a search request (broken up for readability):
https://api.delivery.com/merchant/search/delivery
?client_id=abc123
&address=199 Water St 10038
Handling Responses
Content Types
{
"search_address" : {
"street" : "235 Park Ave S",
"city" : "New York",
"state" : "NY",
},
"merchants": [
{
"id": "3102",
"summary": {
"name": "Azuki Japanese Restaurant",
"cuisines": [
"Japanese"
],
"phone": "555-555-5555",
"description": null,
"overall_rating": "83",
"num_ratings": 79,
"type": "R",
"notes": null
},
"ordering": {
"delivery_processes_card": true,
"payment_types": [
"credit",
"gift card",
"campus card",
"promotions",
"cash"
],
"is_rds": false,
"time_needed": "30",
"specials": [
"10% Off All Orders Over $35",
"10% Off All Orders Over $50"
],
"next_order_time": "2013-08-22 23:15:00",
"minimum": "8.00",
"is_open": true,
"delivery_charge": "0.50",
"delivery_percent": "5.00"
},
"location": {
"distance": "0.0134401220484058",
"street": "239 PARK S AVE",
"city": "NEW YORK",
"state": "NY",
"zip": "10003",
"longitude": -73.987846,
"latitude": 40.737839,
"landmark": "19th & 20th Street"
}
}
]
}
All responses are JSON, as are some request parameters. We don’t support other content types at this time. For example, a search response might look like this:
HTTP Response Codes
The following HTTP response codes are returned by the API. Usually there is additional info included in the body of the response. See Error Handling below.
HTTP Status Code | Reason |
---|---|
200 OK | The request succeeded. |
400 Bad Request | Request was invalid. Check the body for more info. |
401 Unauthorized | Access Token was invalid or not supplied. See Authentication "Authentication"). |
500 System Error | There was an internal error. |
503 Service Unavailable | delivery.com is undergoing maintenance or otherwise unavailable. |
Error Responses
All error responses have this structure:
{
"message": [
{
"code" : "dupe_email",
"user_msg" : "An account already exists for komonster@delivery.com.",
"dev_msg" : "An account already exists for komonster@delivery.com."
}
],
"other_data" : "..."
}
key | description |
---|---|
message | An array of error messages |
code | The error code. Error codes will not change, so you should reference these codes in your logic. |
user_msg | A description of the error that should be helpful to the user. We highly recommend using our descriptions rather than coming up with your own. These are subject to change and so should not be referenced in your logic. |
dev_msg | A description of the error that is helpful to the developer. It might include links to documentation or detailed instructions that aren’t suited to the end user. |
other_data | Some endpoints might send back other data that is useful. Check the documentation for that specific endpoint. |
Handling Multiple Addresses
{
"message": [
{
"code": "loc_multiple_possible",
"user_msg": "Multiple addresses possible.",
"dev_msg": "Multiple addresses possible."
}
],
"addresses": [
{
"street": "1 N Rosedale St",
"neighborhood": null,
"city": "Baltimore",
"sublocality": null,
"state": "MD",
"zip": "21229",
"latitude": 39.28602,
"longitude": -76.6689,
"exactMatch": true,
"unit": null
},
{
"street": "1 S Rosedale St",
"neighborhood": null,
"city": "Baltimore",
"sublocality": null,
"state": "MD",
"zip": "21229",
"latitude": 39.2858,
"longitude": -76.66889,
"exactMatch": true,
"unit": null
}
]
}
In case of multiple locations found for an address.
Example : 1 Rosedale St, Baltimore, MD, United States
HTTP Status Code : 200 OK
Authentication
Overview
Level | Authentication | Description |
---|---|---|
Unauthenticated | client_id | Used for most GET calls such as merchant information, menu items, and general search. |
Password Flow | oauth token | Any POST calls and customer specific calls that require prior authorization. |
Trusted Flow | oauth token | Any calls with credit cards. |
Unauthenticated
All API partners are granted unauthenticated access. Simply append your client_id to the request as such:
https://api.delivery.com/endpoint/?client_id={client_id}
Elevated Access: Password + Trusted Flow
By default, your API partner account will not have Password or Trusted flow. You will need to apply for elevated access (details at the bottom of this page). Once your API partner account is granted elevated access, you will be able to make requests on behalf or our users.
All elevated access requests requires a successful oauth token handshake. The process is pretty complicated so we encourage you to find a framework to help you with the request process.
Documentation of our Obtaining Access Tokens
PASSWORD FLOW If you would like users to be able to sign up / login to their delivery.com accounts through your application, you will need to apply and receive Password Flow from our API manager. We highly encourage all of our API partners to apply for Password Flow as this unlocks more endpoints to tap into delivery.com.
User account creation will not work without having Password Flow granted to your account.
Trusted Flow
Trusted flow is reserved for businesses that have demonstrated success through our ordering API. Since this flow allows you to bypass the credit card pop-up – we have very strict requirements including PCI compliance, business status, company size, and several other key factors.
In many cases, you should be able to create a very powerful application without having trusted flow.
Applying For Password Flow or Trusted Flow
We encourage developers to first create a proof-of-concept application with our API before requesting for elevated access. Successful integrations (that receive repeating orders) can seek out elevated access with a richer set of features (including creation of new users).
Please speak with your Contact at Delivery.com if you have any further questions.
API Updates
Changelog
4/14/2023 - Reorganized API Documentation
5/4/2023 - Fixed a few section issues
7/21/2023 - Fixed some issues with sample data and broken links
9/28/2023 - Fixed Sample menu post
API Documentation
Alcohol
Alcohol: GET Products
Get alcohol products offered by local alcohol merchants. Endpoint supports search and advanced filtering and sort.
HTTP Request
GET /data/search/?search_type=alcohol
Resource Information
Parameter | Value |
---|---|
Response Format | JSON |
Authentication | pass in client_id only |
Rate Limited | Yes |
Authentication
Unauthenticated API request. Simply pass in the client_id. You can receive a client_id after signing up for a developer account.
Full Example URL
https://api.delivery.com/data/search?search_type=alcohol&address=1006+Avenue+of+the+Americas,10018&order_time=ASAP&order_type=delivery&client_id=brewhacks2016
Parameters
All parameter keys should be lowercase; parameter values should all be UTF-8 and URL-encoded.
Parameter name | Type | Description |
---|---|---|
Required Parameters | ||
address | String | The address where the user is. Acceptable formats include ‘Address, City, State’ and ‘Address, Zip’. We’ll validate the address for you. |
latitude | String | The latitude of the search location. Only required if not sending an address. |
longitude | String | The longitude of the search location. Only required if not sending an address. |
order_type | string | Set the order type to either delivery or pickup. |
order_time | string | Time of order. Set to ASAP for as soon as possible on demand delivery. Or, set it for a future order time. Make sure to include the timezone information otherwise it will to default UTC. We recommend ISO8601 2016-04-07T23:45:00-0400. |
Optional Parameters | ||
keyword | string | Search by product name. Supports fuzzy search and advanced prefix search. String must be UTF-8, URL-encoded, and less than 500 characters in length. |
section | string | Alcohol type searching on. Valid values include beer, liquor, wine. Defaults to all. |
subsection | string | Comma delimited list of subcategories to search on. |
filter_size | string | Filter based on size. |
filter_country | string | Filter based on country |
filter_price | integer | Filter based on price groups. This filter does not take in dynamic values. |
limit | integer | Limit the number of X items to return per deepest category level |
limit_if_segmented | integer | Variation to the regular limit parameter. Results will only by limted if 2 or more categories are returned |
sort | string | Define the sort style for the products. Currently support name and price. Prefix the sort by a minus to denote descending sort. ?sort=-name searches Z to A. |
merchant_ids | string | Comma separated list of all merchant ids (or merchant slugs) to search against. This will only override the default merchants ids selected by geolocation if the passed in merchants are in delivery range. |
inexact | boolean | Include inexact=true to perform to search approximate addresses, such as finding all products that are available in a particular zip code, neighborhood, or point of interest. |
Section
Optinal - string
Pass in alcohol type to restrict search. Only pass in one value at a time.
Type | Identifier |
---|---|
All Types | all |
Beer | beer |
Liquor | liquor |
Wine | wine |
?section=wine
Subsection
Optional - string
Comma delimited list of subcategories to search on. The section (wine, liquor, beer) should also be passed in. The filtering system may return unexpected results without specified section (but should still work).
?section=wine&subsection=kosher
?section=wine&subsection=red,white,kosher
?section=wine&subsection=red.pinot-grigio,red.merlot,white.rice
FILTER_SIZE
Optional - string
Filter based on country. Put multiple values in a comma separated list.
?filter_size=750mL,1L
FILTER_PRICE
Optional - string
Filter based on price. Currently this filter does not take in dynamic values. Simply pass in 1, 2, 3, or 4. As the response for filters payload shows.
Price Group | Identifier |
---|---|
null | no filter |
Under $10 | 1 |
$10 to $20 | 2 |
$20 to $30 | 3 |
$30 to $50 | 4 |
$50 and above | 5 |
Defaults to no price filter being applied.
Request Body
Do not supply a request body with this method.
Response Structure
{
"data" : {
"categories" : [ ... ],
"filters" : [ ... ],
"products" : { ... }
"breadcrumbs" : [],
"sort": { ... }
"merchants" : [ ... ]
}
Key | Explanation |
---|---|
Categories | Category tree of all alcohol categories starting. |
Filters | List all the available filters for the currently selected products. |
products | Lists all the product information including the picture thumbnail. The id value links to the product ids listed in the category tree and is used for internal matching only. The unique product_id is product_id (alphanumeric string). |
breadcrumbs | Shows the current location of the search. Breadcrumbs will not work properly if multiple subsection values are listed. |
sort | Available sort options |
merchants | Fully hydrated merchant object |
search_address | This is the geocoded address of your search. You might want to store it for later use in the location API. If passing inexact=true, be sure to check whether is_exact_match is true or false. This will indicate whether the address points to a real location or is just approximate. When dealing with approximate addresses, you’ll need to prompt users for their actual addresses later in the process to add items to their carts. |
Categories
"categories" : [
{
"name" : "Wine",
"value" : "wine",
"key" : "section",
"is_selected" : true,
"children" : [
{
"name" : "Red",
"value" : "red",
"key" : "subsection",
"is_selected" : false,
"children" : [
{
"name" : "Cabernet Sauvignon",
"value" : "red.cabernet-sauvignon",
"key" : "subsection",
"is_selected" : false,
"count" : 47,
"children" : [],
"product_ids" : [4, 10, 21, 39, 195]
}
{
"name" : "Sangiovese",
"value" : "red.sangiovese",
"key" : "subsection",
"is_selected" : false,
"count" : 11,
"children" : [],
"product_ids" : [5, 42, 74, 80, 499]
}
]
}
]
}
],
The results come back as a nested tree of categories starting from the top most beer / liquor / wine category.
- name – title of category
- value / key – used for category filtering
- is_selected – boolean denoting whether category is currently selected (filtered)
- count – number of products matching the filter selection. Parent categories will count all matched children products.
- children – category children of the parent category.
- product_ids – internal product ids only valid for this request. Match the product id to the key of the products object. The product object will include a unique id product_id.
Use the key and value of a child to properly filter categories. For “cabernet Sauvignon”, pass in:
?subsection=red.cabernet-sauvignon
The dot notation denotes that the category is a parent of “red” (wine).
FILTERS
"filters" : [
{
"name" : "Country",
"key" : "filter_country",
"multi_selectable" : true,
"children" : [
{
"name" : "France",
"value" : "france",
"is_selected" : false,
"count" : 32
}
{
"name" : "United States",
"value" : "united-states",
"is_selected" : false,
"count" : 93
}
]
}
{
"name" : "Price",
"key" : "filter_price",
"multi_selectable" : true,
"children" : [
{
"name" : "$30 to $50",
"value" : 4,
"is_selected" : false,
"count" : 19
}
{
"name" : "$20 to $30",
"value" : 3,
"is_selected" : false,
"count" : 19
}
]
}
{
"name" : "Size",
"key" : "filter_size",
"multi_selectable" : true,
"children" : [
{
"name" : "750ml",
"value" : "750ml",
"is_selected" : false,
"count" : 262
}
{
"name" : "500ml",
"value" : "500ml",
"is_selected" : false,
"count" : 125
}
]
}
],
- key / value – Used for filtering
- multi_selectable – all filters are multi-selectable but this may change in the future.
- count – number of products matching the current filter if not selected; or, the number of products that will match the filter once it is selected.
Use the key and value of the child to filter:
?filter_country=france
?filter_price=3,4
?filter_size=750ml,500ml
Products
"products" : {
"4" : {
"id" : 4,
"product_id" : "39773",
"merchant_ids" : [72167],
"name" : "Caymus Vineyards Cabernet Sauvignon Napa Valley",
"type" : "wine",
"size" : "750ml",
"price" : 71.99,
"size_price" : [
{
"size": "750ml",
"price": 71.99,
"quantity": 1
}
{
"size": "1L",
"price": 120.99,
"quantity": 1
}
],
"categories" : ["red.cabernet-sauvignon"],
"tags" : [
{
"key" : "grape",
"value" : ["red", "cabernet-sauvignon"]
},
{
"key" : "brand",
"value" : "Caymus Vineyards"
},
{
"key" : "origin",
"value" : "Sacremento, California",
},
{
"key": "info",
"value": ["sparkling"]
}
],
"image" : "https://dcom-standardized-data-dev.s3.amazonaws.com/master_list/images/55e879328f3b0b88478b5e71/55e879328f3b0b88478b5e71_0.jpg",
"description": "....."
}
},
- id – internal id used to link the product to the ids listed in the categories tree.
- product_id – “liquid id” of the product. This id cannot be used for checkout as it does not specify the quantity / volume / container type. Please first do a call to products/{id} endpoint. This will return all permutations of the alcohol item.
- name – product name.
- type – primary alcohol type: beer, wine, or liquor.
- size – default volume or pack information
- price – price of the item for the default volume
- size_price – all price/size options
- categories – all categories that the item currently matches in the request. This will not show all categories the item is categorized under.
- tags – alcohol tags
- image – url of item image
- description – item description
Breadcrumbs
Lists the path to the current filtering location. Useful for navigational purposes.
SORT
"sort": {
"key": "sort",
"options" : [
{
"title" : "Name A to Z",
"value" : "name",
"is_selected" : true
},
{
"title" : "Name Z to A",
"value" : "-name",
"is_selected" : false
},
{
"title" : "Lowest Price",
"value" : "price",
"is_selected" : false
},
{
"title" : "Highest Price",
"value" : "-price",
"is_selected" : false
},
]
},
Lists all the sort options. Use the key and value to set the sort.
?sort=-name // sorts Z to A
?sort=price // sorts low to high price
Merchants
Lists the merchant information including the name, address, distance from inputted address, and order availability.
Alcohol: GET Merchants provides more information about the merchant object.
Alcohol: GET Products/{id}
Get information for a single alcohol product. Request
HTTP Request
GET /data/product/{product_id}?merchant_id={merchant_id}
Resource Information
Parameter | Value |
---|---|
Response Format | JSON |
Authentication | pass in client_id only |
Rate Limited. | Yes |
Authentication
Unauthenticated API request. Simply pass in the client_id. You can receive a client_id after signing up for a developer account.
Full Example URL
https://api.delivery.com/data/product/11234?merchant_id=62184&show_description=true&client_id=brewhacks2016
Parameters All parameter keys should be lowercase; parameter values should all be UTF-8 and URL-encoded.
Parameter Name | Type | Description |
---|---|---|
Required Parameters | ||
product_id | string | Alphanumeric string identifying the product selection. Enter this value directly into the url route. |
merchant_id | integer | Id of the merchant_id currently offering this product. |
Optional Parameters | ||
show_description | boolean | Set to true to return the full item description (when available). |
Product_id Uniqueness
- The product_id is the liquid_id.
- Items containing the same liquid will usually have the same product_id.
- However, sometimes the same “liquid” products will be assigned different product_ids.
The product_id can not be used for checkout. As this only specifies the alcohol liquid (product type). Alcohol products have varying volume, quantity, and container types. The “children” key in the response will return all permutations (volume, container, and quantity) of the bottles. Use that id to make a call to checkout.
The product_id is useful to get all similar products with varying volume / container type / quantity – especially during item browsing.
Merchant Id The merchant_id must be passed in so the appropriate item information is returned. Inventory and prices are based on availability from local merchants.
Merchant ids can be obtained by issuing a general a call to Get alcohol products.
Response
{
"item": [
{
"available": true,
"children": [{ ... }],
"description": "Some description",
"id": "11234",
"image": "https://dcom-standardized-data-dev.s3.amazonaws.com/master_list/images/55d25ef97bad77e5628b6df0/5616bd388fa80.png",
"increment": 1,
"max_price:": 33.99,
"max_qty": 25,
"merchant_id": 62184,
"min_qty": 1,
"name": "Bacardi Rum Gold",
"popular_flag": false,
"price": 5.99,
"tags": [ ... ],
"type": "item",
"unique_id": ""
}
]
}
Parameter | Type | Explanation |
---|---|---|
available | boolean | Is the item currently in stock? |
children | object | Lists all item size/price options |
description | string | Item description |
id | string | product_id |
image | string | Url of image thumbnail |
increment | integer | Used internally |
max_price | float | Maximum price of all available options |
max_qty | integer | Maximum number of items that can be ordered at once |
merchant_id | integer | Merchant id of the inventory lookup |
min_qty | integer | Minimum number of items that must be purchased |
name | string | Item title |
popular_flag | boolean | Used internally |
price | float | Minimum price of all available options |
tags | object | Additional item tagging information |
type | string | Defaults to “item” |
unique_id | string | Not currently used |
Children
children: [
{
"children": [],
"description": "",
"id": "56fa9db6275af6b84a8b4ecc",
"max_price": 0,
"name": "1.75L",
"price": 33.99,
"type": "option",
"unique_id": ""
},
{
"children": [],
"description": "",
"id": "56fa9f8f275af6b84a8b6911",
"max_price": 0,
"name": "1L",
"price": 24.99,
"type": "option",
"unique_id": ""
},
... all other options
}]
Parameter | Type | Explanation |
---|---|---|
children | object | Not currently used |
id | string | Unique id used for checkout |
max_price | int | Not currently used |
name | string | Size / container / quantity information |
price | float | Price of item option |
type | string | Set to “option” (vs. “item” from earlier) |
unique_id | string | Not currently used |
The unique_id is used to make a call to checkout. The id uniquely identifies:
merchant_id / product_id (liquid) / size_option
Alcohol: GET Merchants
Get a list of nearby alcohol merchants.
Request
Response
{
"data": {
"merchants": {
"27484" : {
"id": "27484",
"search_address": null,
"deliverable": true,
"location" : { },
"summary" : { },
"ordering" : { ... },
"standardized_data_default" : 1,
"inventory_type_overview" : {
"B" : 154
}
}
},
"59662" : {},
"61527" : {},
"search_address" : {
// geolocation data of entered address
}
}
}
HTTP Request
GET /data/search?search_type=MerchantList
Resource | Information |
---|---|
Parameter | Value |
Response Format | JSON |
Authentication | pass in client_id only |
Rate Limited. | Yes |
AUTHENTICATION Unauthenticated API request. Simply pass in the client_id. You can receive a client_id after signing up for a developer account.
Full Example URL
https://api.delivery.com/data/search?search_type=MerchantList&order_type=delivery&order_time=ASAP&address=1006+Avenue+of+the+Americas,10018&client_id=brewhacks2016
Parameters
All parameter keys should be lowercase; parameter values should all be UTF-8 and URL-encoded.
Parameter Name | Type | Description |
---|---|---|
Required Parameters | ||
search_type | string | Set to MerchantList |
address | String | The address where the user is. Acceptable formats include ‘Address, City, State’ and ‘Address, Zip’. We’ll validate the address for you. |
order_type | string | Set the order type to either delivery or pickup. |
order_time | string | Time of order. Set to ASAP for as soon as possible on demand delivery. Or, set it for a future order time. Make sure to include the timezone information otherwise it will to default UTC. We recommend ISO8601 2016-04-07T23:45:00-0400. |
TOP LEVEL Parameter |Type |Explanation -|-|- merchants |object |Collection of alcohol merchants in range search_addres |object |Geolocation of entered address
MERCHANTS
The GET Merchant Info endpoint is the dedicated resource on the merchant object but we’ll all the alcohol-specific parameters:
Parameter | Type | Explanation |
---|---|---|
id | string | Merchant id |
standardized_data_default | boolean | Use internally |
inventory_type_overview | object | Describes the merchant’s alcohol inventory type and quantity. B = beer; L = liquor; W = wine. |
Merchant
Merchant Representation
A merchant is represented in the delivery.com API by the data structures described below. The data structure has a few small differences depending on which API it is being sent in.
A merchant also has a menu, hours, and ratings.
Merchant from search example
{
"id": "835",
"summary": {
"name": "Barking Dog Luncheonette",
"cuisines": [
"American",
"Sandwiches"
],
"phone": "212-861-3600",
"description": "Voted as the \"Best Budget Brunch\" by the New York Post, Barking Dog Luncheonette serves diner classics like omelettes, sandwiches, burgers and more! Order in your favorite brunch today!",
"overall_rating": 72,
"num_ratings": 129,
"type": "R",
"type_label": "Restaurant",
"notes": [
"In order to process your credit card, We require that you provide your CVV code printed on the back of your credit card. The restaurant will be contacting you after you place your order to obtain this information."
],
"url_stub": {
"geo": "nyc",
"merchant": "barking-dog-luncheonette-10075"
},
"activation_date": "2003-03-06"
},
"ordering": {
"delivery_processes_card": true,
"payment_types": [
"credit",
"gift card",
"promotions",
"cash"
],
"is_rds": false,
"time_needed": 0,
"specials": [
"10% Off All Orders Over $60"
],
"next_order_time": "2014-01-27 22:45:00",
"minimum": 5,
"is_open": true,
"delivery_charge": 0,
"delivery_percent": 0
},
"location": {
"distance": 0.34532518731836,
"street": "1453 YORK AVE",
"city": "NEW YORK",
"state": "NY",
"zip": "10075",
"longitude": -73.951241,
"latitude": 40.770489,
"landmark": "Corner of 77th Street"
}
}
Merchant from info exmaple
{
"message": [],
"merchant": {
"id": "835",
"location": {
"street": "1453 YORK AVE",
"city": "NEW YORK",
"state": "NY",
"zip": "10075",
"longitude": -73.951241,
"latitude": 40.770489,
"landmark": "Corner of 77th Street"
},
"summary": {
"name": "Barking Dog Luncheonette",
"phone": "212-861-3600",
"description": "Voted as the \"Best Budget Brunch\" by the New York Post, Barking Dog Luncheonette serves diner classics like omelettes, sandwiches, burgers and more! Order in your favorite brunch today!",
"overall_rating": 72,
"num_ratings": 129,
"type": "R",
"notes": "Array",
"cuisines": [
"American",
"Sandwiches"
],
"url_stub": {
"geo": "nyc",
"merchant": "barking-dog-luncheonette-10075"
},
"activation_date": "2003-03-06"
},
"ordering": {
"availability": {
"pickup": false,
"delivery": false,
"next_pickup_time": "2014-01-28T07:00:00-0500",
"next_delivery_time": "2014-01-28T07:00:00-0500"
},
"payment_types": [
"credit",
"gift card",
"promotions",
"cash"
],
"time_needed": "0",
"specials": [
"10% Off All Orders Over $60"
],
"order_type": "delivery"
}
}
}
MERCHANT.SUMMARY
General information about the merchant
Property Name | Value | Description |
---|---|---|
id | String | Unique identifier for this merchant. |
name | String | Name of the merchant. |
cuisines | String[] | Array of different cuisines that this merchant offers. |
phone | String | Merchant phone number. |
description | String | Description generated by the merchant. |
overall_rating | Integer | Rating of the merchant generated by user reviews, on a scale of 1-100. 0 means that the merchant hasn’t had any reviews yet. |
type | R/C/F/I/W/U/P/Z | Type of merchant. See Merchant Search. |
notes | String | Extra info about ordering from this merchant that is usually more important to the user than the description. E.g. ‘Adding additional meat to a salad is $1.00 extra.’ |
url_stub | Object | Ignore and use summary.url instead. |
url | String | (TODO)A link to the merchant listing on delivery.com. We’ll handle redirecting mobile users as necessary. |
activation_date | String | The date that the merchant went live on delivery.com. The format is YYYY-MM-DD. |
MERCHANT.ORDERING
Data related to placing orders from this merchant.
Property Name | Value | Description |
---|---|---|
payment_types | String[] | The different payment options that this merchant accepts. |
is_rds | true/false | If true, this merchant uses a 3rd party delivery service to deliver orders. |
time_needed | Integer | How much time a merchant needs to prepare an order. For example, if you’re allowing customers to book future orders, you shouldn’t let them book a pickup order for the minute the merchant opens. |
specials | String[] / null | Array of specials that this merchant offers. |
last_or_next_order_time | String | If the merchant is currently accepting orders, this is the last time that you can place an order today. If they’re not accepting orders, it’s the next time that you can place an order for. |
minimum | Float | Minimum order size for pickup/delivery depending on which endpoint you’re calling. |
is_open | true/false | Whether or not this merchant is open at the current point in time. |
delivery_charge | Float | The flat fee that this merchant charges for delivery. |
delivery_percent | Float | The percentage fee that this merchant charges for delivery. This ranges from 0-1, so 15% would be represented as 0.15. |
MERCHANT.LOCATION
Location Location object.
Property Name | Value | Description |
---|---|---|
distance | Double | The distance in miles from this merchant to the searched location. |
landmark | String | Extra info about where the merchant is located. |
MERCHANT.ORDERING
Search specific properties
Property Name | Value | Description |
---|---|---|
favorite | true/false | Whether or not the user has favorited this merchant. You must submit an access token with your request to see this parameter. |
delivery_processes_card | true/false | If true, delivery.com charges the customer’s credit card. If false, the merchant charges it. |
MERCHANT.ORDERING.AVAILABILITY
Parameter | Type | Explanation |
---|---|---|
active | boolean | Is the merchant currently active |
pickup | boolean | Is pickup available at the requested order_time |
delivery | boolean | Is pickup available at the requested order_time |
pickup_supported | boolean | Does the merchant even support pickup? |
delivery_supported | boolean | Does the merchant even support delivery? |
last_pickup_time | time | If pickup available it will show timestamp; otherwise null. |
last_delivery_time | time | If delivery available it will show timestamp; otherwise null. |
next_pickup_time | time/null | If pickup not available it will show timestamp; otherwise null. |
next_delivery_time | time/null | If delivery not available it will show tiemstamp; otherwise null. |
pickup_estimate | integer | Estimated pickup time |
delivery_estimate | integer | Estimated delivery time |
Merchant Search
View a list of merchants that service a given location. This endpoint does not require authentication, but will return additional information if an access token is included in the Authorization HTTP header.
Request
HTTP Request
GET /merchant/search/{method}
Parameters
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
method | delivery | pickup |
address | String | The address where the user is. Acceptable formats include ‘Address, City, State’ and ‘Address, Zip’. We’ll validate the address for you. See more in the Response section. Note: this is only required if not sending a latitude/longitude. |
latitude | String | The latitude of the search location. Only required if not sending an address. |
longitude | String | The longitude of the search location. Only required if not sending an address. |
Optional Parameters | ||
access_token | String | Include this to see whether a user has favorited each merchant. |
merchant_type | R/C/F/I/W/U/P/Z | Include this to filter search results to a certain merchant type. R - Restaurant. C - Caterer. F - Florist. I - Grocery Store. W - Wine and Liquor Store. U - Drug/Convenience Store. P - Pet Store. Z - Tobacco Shop |
inexact | true | Include this to perform to search approximate addresses, such as finding all merchants who are near a particular zip code, neighborhood, or point of interest. |
Request Body
Do not supply a request body with this method.
Responses
{
"search_address": {
"street": "235 PARK AVE S",
"zip_code": "10003",
"state": "NY",
"city": "NEW YORK",
"latitude": 40.73771,
"longitude": -73.987949
},
"message": [ ],
"promoted_merchants_id": [
"57",
...
],
"merchants": [
{
"id": "57",
"favorite": false,
"summary": {
"name": "Gramercy Bagels",
"cuisines": [
"Sandwiches",
"Bagelry"
],
"phone": "555-555-5555",
"description": "",
"overall_rating": 75,
"num_ratings": 138,
"type": "R",
"type_label": "Restaurant",
"notes": null,
"url": {
"geo_tag": "nyc",
"short_tag": "gramercy-bagels",
"complete": "https://staging.delivery.com/nyc/gramercy-bagels"
},
"activation_date": "2000-11-01"
},
"ordering": {
"delivery_processes_card": true,
"payment_types": [
"credit",
"gift card",
"promotions",
"cash"
],
"is_rds": false,
"time_needed": 30,
"specials": [
{
"name": "10% Off for First Time Users",
"type": "F"
}
],
"last_or_next_order_time": "2014-06-03 22:15:00",
"minimum": 8,
"is_open": true,
"delivery_charge": 0,
"delivery_percent": 0
},
"location": {
"distance": 0.18608809903916,
"street": "246 3rd Ave",
"city": "New York",
"state": "NY",
"zip": "10010",
"longitude": -73.984444,
"latitude": 40.737263,
"landmark": "Between 20th ;amp; 21st."
}
}
...
],
"verticals": [
{
"type": "R",
"count": 389,
"label": "Restaurant"
},
{
"type": "C",
"count": 63,
"label": "Caterer"
}
...
],
"cuisines": [
"Afghan",
"American",
"Argentinian",
"Asian",
"Bagelry",
"Barbeque",
"Brazilian",
"Breakfast",
"Burgers",
"Cafe",
"Caribbean",
"Cheesesteaks",
"Chinese",
"Cuban",
"Deli",
"Desserts",
"Diner",
"Empanadas",
...
],
"popular_cuisines": [
"Sandwiches",
"Italian",
"American",
"Japanese",
"Pizza"
...
]
}
Success
HTTP 200 OK
Property Name | Value | Description |
---|---|---|
search_address | Location | This is the geocoded address that you searched for. You might want to store it for later use in the location API. If passing inexact=true, be sure to check whether is_exact_match is true or false. This will indicate whether the address points to a real location or is just approximate. When dealing with approximate addresses, you’ll need to prompt users for their actual addresses later in the process to add items to their carts. |
merchants | Merchant[] | Array of merchants that service that location |
cuisines | String[] | Array of cuisines that are available to this location |
verticals | vertical[] | Array of json objects containing information about verticals available to that location. See example response above. |
No Results Found
{
"search_address": {
"street": "7452 STONEBROOK DR",
"zip_code": "48187",
"state": "MI",
"city": "CANTON",
"latitude": 42.338348,
"longitude": -83.51164
},
"message": [
{
"code": "no_delivery_results",
"user_msg": "Sorry, no results were found",
"dev_msg": "Sorry, no results were found"
}
],
"promoted_merchants_id": [],
"merchants": [],
"cuisines": []
}
HTTP 200 OK
Ambiguous Location
{
"message": [
{
"code": "loc_multiple_possible",
"user_msg": "Multiple addresses possible.",
"dev_msg": "Multiple addresses possible."
}
],
"addresses": [
{
"street": "1 N Rosedale St",
"city": "Baltimore",
"state": "MD",
"zip": "21229",
"latitude": 39.28602,
"longitude": -76.6689,
"exactMatch": true
},
{
"street": "1 S Rosedale St",
"city": "Baltimore",
"state": "MD",
"zip": "21229",
"latitude": 39.2858,
"longitude": -76.66889,
"exactMatch": true
}
]
}
HTTP 400 Bad Request
Property Name | Value | Description |
---|---|---|
addresses | Location | Possible addresses that the user could have meant. You should show these to the user and have him select the one that he meant. |
Invalid Address
{
"message": [
{
"code": "invalid_address",
"user_msg": "We could not find the address that you submitted. Please double check all the fields and try again.",
"dev_msg": "This address could not be validated."
}
]
}
HTTP 400 Bad Request
Merchant Info
View general info for a merchant. The normal return type is a Merchant.
Request
HTTP Request
Example
{
"message": [
],
"merchant": {
"id": "3215",
"location": {
"street": "1584 2nd Ave",
"city": "New York",
"state": "NY",
"zip": "10028",
"longitude": -73.953285,
"latitude": 40.775536,
"landmark": "Corner of 2nd Ave. & 82nd St."
},
"summary": {
"name": "Wasabi Lobby",
"phone": "212-988-8882",
"description": "Wasabi Lobby is an Asian fusion restaurant specializing in all things creative and innovative when it comes to sushi rolls. Accompany your meal with a drink from Wasabi Lobby's selection of sake, beer, or wine!",
"overall_rating": 82,
"num_ratings": 164,
"type": "R",
"notes": "Array",
"cuisines": [
"Japanese"
],
"url": {
"geo_tag": "nyc",
"short_tag": "wasabi-lobby",
"complete": "https:\/\/staging.delivery.com\/nyc\/wasabi-lobby"
},
"activation_date": "2005-09-26"
},
"ordering": {
"availability": {
"pickup": false,
"delivery": false,
"next_pickup_time": "2014-01-28T11:30:00-0500",
"next_delivery_time": "2014-01-28T11:30:00-0500"
},
"payment_types": [
"credit",
"gift card",
"promotions",
"cash"
],
"time_needed": "15",
"specials": [
{
"name": "10% Off for First Time Users",
"type": "F"
}
],
"order_type": "delivery"
},
"minimum": {
"delivery": {
"lowest": 10,
"highest": 10
},
"pickup": 5
}
}
}
GET /merchant/{merchant_id}/
Parameters
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
merchant_id | Integer | The id of the merchant from the Search endpoint. |
Optional Parameters | ||
address | string | Passing an address will display the exact delivery fee for the given location, otherwise a range of delivery fees will be returned. |
Request Body
Do not supply a request body with this method.
Response
Success
HTTP 200 OK
Invalid Merchant Id
Example
{
"message": [
{ "code" : "no_rest", "user_msg" : "Sorry, we weren't able to find the merchant." },
]
}
This is returned when an invalid merchant id is passed.
HTTP 400 Bad Request
Merchant Hours
Get a merchant’s business and delivery hours. Notes:
- There may be multiple open and close times in a single day if the merchant closes during and reopens during the day.
- A close time may be earlier than open time, in which case the close time is in the morning of the next day.
HTTP Request
Success Response
{
"message": [],
"merchant_id": "64994",
"merchant_name": "Kestane Kebab",
"standard_schedule": {
"business": {
"sunday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "23:30"
}
]
},
"monday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
]
},
"tuesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
]
},
"wednesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
]
},
"thursday": {
"times_open": [
{
"start": "11:00",
"end": "00:00"
}
]
},
"friday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "00:00"
}
]
},
"saturday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "00:00"
}
]
}
},
"delivery": {
"sunday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "23:30"
}
]
},
"monday": {
"times_open": []
},
"tuesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
]
},
"wednesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
]
},
"thursday": {
"times_open": [
{
"start": "11:00",
"end": "00:00"
}
]
},
"friday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "00:00"
}
]
},
"saturday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "00:00"
}
]
}
}
},
"current_schedule": {
"business": {
"thursday": {
"times_open": [
{
"start": "11:00",
"end": "00:00"
}
],
"date": "2014-02-13"
},
"friday": {
"times_open": [],
"date": "2014-02-14"
},
"saturday": {
"times_open": [
{
"start": "09:00",
"end": "17:00"
}
],
"date": "2014-02-15"
},
"sunday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-16"
},
"monday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-17"
},
"tuesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-18"
},
"wednesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-19"
}
},
"delivery": {
"thursday": {
"times_open": [
{
"start": "11:00",
"end": "00:00"
}
],
"date": "2014-02-13"
},
"friday": {
"times_open": [],
"date": "2014-02-14"
},
"saturday": {
"times_open": [
{
"start": "09:00",
"end": "17:00"
}
],
"date": "2014-02-15"
},
"sunday": {
"times_open": [
{
"start": "00:00",
"end": "00:30"
},
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-16"
},
"monday": {
"times_open": [],
"date": "2014-02-17"
},
"tuesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-18"
},
"wednesday": {
"times_open": [
{
"start": "11:00",
"end": "23:30"
}
],
"date": "2014-02-19"
}
},
"availability": {
"pickup": true,
"delivery": true
}
}
}
GET /merchant/{merchant_id}/hours
Parameters
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
merchant_id | Integer | The id of the merchant from the Search endpoint. |
Optional Parameters | ||
utc | true | false |
iso | true | false |
Request Body
Do not supply a request body with this method.
HTTP 200 OK
Property Name | Value | Description |
---|---|---|
merchant_name | String | Merchant name. |
standard_schedule | Object | The regular operating schedule of this merchant. |
standard_schedule.business | Object[] | The business hours of the merchant. If they accept pickup orders, these are also the hours that the merchant is available for pickup orders. If they’re closed on a Sunday, Sunday is omitted. |
day | String | The day of week in the format “sunday”. |
start | String | Time they open. If utc is false, the format is 07:00. If utc is true, the format is 2014-01-26T12:00:00+0000 |
end | String | Time they close. Same format as open. |
standard_schedule.delivery | Object[] | The delivery hours of the merchant. Same format as business hours. If they don’t deliver on a Sunday, Sunday is omitted. |
current_schedule | Object | The operating schedule of this merchant for this particular week. The merchant could be closed on a day that they’re usually open due to a holiday or bad weather. |
date | String | The date for each day’s hours. Format is YYYY-MM-DD. |
current_schedule.availability.pickup | true | false |
current_schedule.availability.delivery | true | false |
Merchant Deactivated
Example
{
"message": [
{ "code" : "deactivated", "user_msg" : "The merchant requested has been deactivated." },
]
}
This is returned when a merchant isn’t currently accepting orders from delivery.com.
HTTP 400 Bad Request
Invalid Merchant Id
Example
{
"message": [
{ "code" : "bad_id", "user_msg" : "Sorry, we weren't able to find the merchant." },
]
}
This is returned when an invalid merchant id is passed.
HTTP 400 Bad Request
Schedule not found
Example
{
"message": [
{ "code" : "not_found", "user_msg" : "Sorry, we could not find a schedule for that merchant." }
]
}
This is returned when a schedule can’t be found for this merchant. TODO: WHY?
HTTP 400 Bad Request
Merchant Schedule
{
"day" : 1,
"startTime" : "08:30",
"endTime" : "21:00",
}
The merchant schedule is an array of shifts. A shift is an object:
Property Name | Value | Description |
---|---|---|
id | integer | The id of the shift |
day | integer | Required if weekly shift – The day of the week as such: Sunday = 0, Monday = 1, …, Saturday = 6 |
date | string | Required if holiday shift – The date of the year in YYYY-mm-dd format |
startTime | string | Required – The time the shift begins in HH:mm format |
endTime | string | Required – The time the shift ends in HH:mm format. The endTime must come after startTime. In the case of a shift going past midnight, set the end time to 24:00, then create a new shift for the second day starting at 00:00. |
A post to create a schedule for a merchant would look like this:
POST merchant schedule
{
"merchantId": 1234,
"schedule": {
"business": [
{
"day": 1,
"startTime": "08:30",
"endTime": "21:00"
},
{
"day": 2,
"startTime": "08:30",
"endTime": "21:00"
},
{
"day": 3,
"startTime": "08:30",
"endTime": "21:00"
}
],
"delivery": [
{
"day": 1,
"startTime": "10:00",
"endTime": "19:00"
},
{
"day": 2,
"startTime": "10:00",
"endTime": "19:00"
},
{
"day": 3,
"startTime": "10:00",
"endTime": "19:00"
}
],
"holidayDelivery": [
{
"date": "2014-05-31",
"startTime": "10:00",
"endTime": "14:00"
}
],
"holidayBusiness": [
{
"date": "2014-05-31",
"startTime": "10:00",
"endTime": "14:00"
}
]
}
}
POST /merchant/admin/schedule
The ‘holidayDelivery’ and ‘holidayBusiness’ arrays are used to override the weekly schedule for a given date. To close a merchant for a given date, set the ‘startTime’ and ‘endTime’ to the same time for both business and delivery.
Business hours define a merchant’s operating hours, if the merchant offers pickup, these are the hours available for pickup. Delivery hours must be entirely within business hours. If the merchant only offers delivery, the business hours still must encompass or match the delivery hours.
To make updates to hours, simply include the id:
PUT merchant schedule
{
"merchantId" : "1234",
"schedule" : [
{
"business" : [
{
"id" : 4597,
"day" : 1,
"startTime" : "08:30",
"endTime" : "21:00",
},
],
"delivery" : [
{
"id" : 4599,
"day" : 1,
"startTime" : "10:00",
"endTime" : "19:00",
},
],
"holidayDelivery" : [
],
"holidayBusiness" : [
],
}
]
}
PUT /merchant/admin/schedule
Fetching the merchant schedule requires the merchantId:
GET merchant schedule
GET /merchant/admin/schedule?merchantId=1234
Response:
{
"schedule" : [
{
"business" : [
{
"id" : 5678,
"day" : 1,
"date" : "2017-11-27",
"startTime" : "08:30",
"endTime" : "21:00",
},
{
"id" : 5679,
"day" : 2,
"date" : "2017-11-28",
"startTime" : "08:30",
"endTime" : "21:00",
},
{
"id" : 5680,
"day" : 3,
"date" : "2017-11-29",
"startTime" : "08:30",
"endTime" : "21:00",
},
],
"delivery" : [
{
"id" : 5681,
"day" : 1,
"date" : "2017-11-27",
"startTime" : "10:00",
"endTime" : "19:00",
},
{
"id" : 5682,
"day" : 2,
"date" : "2017-11-28",
"startTime" : "10:00",
"endTime" : "19:00",
},
{
"id" : 5683,
"day" : 3,
"date" : "2017-11-29",
"startTime" : "10:00",
"endTime" : "19:00",
},
],
"holidayDelivery" : [
{
"id" : 5684,
"day" : 0,
"date" : "2017-12-31",
"startTime" : "10:00",
"endTime" : "14:00",
},
],
"holidayBusiness" : [
{
"id" : 5685,
"day" : 0,
"date" : "2017-12-31",
"startTime" : "10:00",
"endTime" : "14:00",
},
],
}
]
}
DELETE merchant schedule
Deletion requires a comma separated list of ids along with the merchant id:
DELETE /merchant/admin/schedule?merchantId=1234&scheduleIds=7894,15967
If you prefer to delete all schedules, you may use the truncate call:
DELETE /merchant/admin/schedule/truncate?merchantId=1234
Merchant Menu
View a merchant’s menu.
Menu Request
HTTP Request
{
"schedule": [
{
"id": 2,
"times": [
{
"day": "Monday",
"from": "2013-09-30T15:00:00+0000",
"to": "2013-09-30T20:00:00+0000"
},
{
"day": "Tuesday",
"from": "2013-10-01T15:00:00+0000",
"to": "2013-10-01T20:00:00+0000"
},
{
"day": "Wednesday",
"from": "2013-10-02T15:00:00+0000",
"to": "2013-10-02T20:00:00+0000"
},
{
"day": "Thursday",
"from": "2013-09-26T15:00:00+0000",
"to": "2013-09-26T20:00:00+0000"
},
{
"day": "Friday",
"from": "2013-09-27T15:00:00+0000",
"to": "2013-09-27T20:00:00+0000"
},
{
"day": "Saturday",
"from": "2013-09-28T16:00:00+0000",
"to": "2013-09-28T20:00:00+0000"
},
{
"day": "Sunday",
"from": "2013-09-29T16:00:00+0000",
"to": "2013-09-29T20:00:00+0000"
}
]
},
{
"id": 4,
"times": [
{
"day": "Monday",
"from": "2013-09-30T21:00:00+0000",
"to": "2013-09-30T23:00:00+0000"
},
{
"day": "Tuesday",
"from": "2013-10-01T21:00:00+0000",
"to": "2013-10-01T23:00:00+0000"
},
{
"day": "Wednesday",
"from": "2013-10-02T21:00:00+0000",
"to": "2013-10-02T23:00:00+0000"
},
{
"day": "Thursday",
"from": "2013-09-26T21:00:00+0000",
"to": "2013-09-26T23:00:00+0000"
},
{
"day": "Friday",
"from": "2013-09-27T21:00:00+0000",
"to": "2013-09-27T23:00:00+0000"
},
{
"day": "Saturday",
"from": "2013-09-28T21:00:00+0000",
"to": "2013-09-28T23:00:00+0000"
},
{
"day": "Sunday",
"from": "2013-09-29T21:00:00+0000",
"to": "2013-09-29T23:00:00+0000"
}
]
}
],
"warnings": [
{
"type": "alcohol",
"items": [
"N2",
"N8"
]
},
{
"type": "tobacco",
"items": [
"N10"
]
}
],
"menu": [
{
"id": "N1",
"name": "Test Menu",
"description": "Items of each type are represented here.",
"type": "menu",
"children": [
{
"id": "N2",
"name": "Simple Item",
"description": null,
"schedule": [
2,
4
],
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "5.99",
"type": "item",
"children": [
{
"id": "N56",
"name": "Simple Item IMAGES",
"url": "/images/path/1234.jpg",
"description": null,
"type": "image",
"children": []
}
]
},
{
"id": "N3",
"name": "Item, Price Group",
"description": null,
"min_qty": "1.00",
"max_qty": "25.00",
"price": "1.99",
"max_price": "3.99",
"type": "item",
"children": [
{
"id": "N4",
"name": "Pick One",
"description": null,
"min_selection": "1",
"max_selection": "1",
"type": "price group",
"children": [
{
"id": "N5",
"name": "Small",
"description": null,
"price": "1.99",
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N6",
"name": "Medium",
"description": null,
"price": "2.99",
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N7",
"name": "Large",
"description": null,
"price": "3.99",
"max_price": null,
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N8",
"name": "Item, Option Group : Single",
"description": null,
"schedule": [
4
],
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "5.99",
"type": "item",
"children": [
{
"id": "N11",
"name": "Single Option Group",
"description": null,
"min_selection": "1",
"max_selection": "1",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N12",
"name": "Un",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N13",
"name": "Dos",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N14",
"name": "Tres",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N9",
"name": "Item, Option Group : Multiple",
"description": null,
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "5.99",
"type": "item",
"children": [
{
"id": "N15",
"name": "Multiple Option Group",
"description": null,
"min_selection": "0",
"max_selection": "3",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N16",
"name": "Salt",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N17",
"name": "Pepper",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N18",
"name": "Spice",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N10",
"name": "Item, Option Group : Quantity",
"description": null,
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "5.99",
"type": "item",
"children": [
{
"id": "N19",
"name": "Option Group Quantity (Select 5)",
"description": null,
"min_selection": "5",
"max_selection": "5",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N20",
"name": "Option 1",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "5.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N21",
"name": "Option 2",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "5.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N22",
"name": "Option 3",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "5.00",
"increment": "1.00",
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N23",
"name": "Item, Option Group : Upto One",
"description": null,
"schedule": [
2
],
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "9.98",
"type": "item",
"children": [
{
"id": "N24",
"name": "Optional Condiments",
"description": null,
"min_selection": "0",
"max_selection": "1",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N25",
"name": "Egg Roll",
"description": null,
"price": "1.99",
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N26",
"name": "Tuna Roll",
"description": null,
"price": "2.99",
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N27",
"name": "Jellyfish Roll",
"description": null,
"price": "3.99",
"max_price": null,
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N28",
"name": "Item, Nested Option Group",
"description": null,
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "5.99",
"type": "item",
"children": [
{
"id": "N29",
"name": "Choice of Combo",
"description": null,
"min_selection": "1",
"max_selection": "1",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N30",
"name": "Burger and Soda",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": [
{
"id": "N33",
"name": "Choice of Soda",
"description": null,
"min_selection": "1",
"max_selection": "1",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N34",
"name": "Pepsi",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N35",
"name": "Coke",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N36",
"name": "Sprite",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N37",
"name": "Fanta",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N31",
"name": "Pizza and Soda",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": [
{
"id": "N39",
"name": "Choice of Soda",
"description": null,
"min_selection": "1",
"max_selection": "1",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N40",
"name": "Pepsi",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N41",
"name": "Coke",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N42",
"name": "Sprite",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N43",
"name": "Fanta",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N32",
"name": "Chowmein and Soda",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": [
{
"id": "N38",
"name": "Choice of Soda",
"description": null,
"min_selection": "1",
"max_selection": "1",
"sel_dep": 0,
"type": "option group",
"children": [
{
"id": "N44",
"name": "Pepsi",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N45",
"name": "Coke",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N46",
"name": "Sprite",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
},
{
"id": "N47",
"name": "Fanta",
"description": null,
"price": null,
"max_price": null,
"type": "option",
"children": []
}
]
}
]
}
]
}
]
},
{
"id": "N48",
"name": "Item, Dozen Bagels",
"description": null,
"min_qty": "1.00",
"max_qty": "25.00",
"price": "5.99",
"max_price": "5.99",
"type": "item",
"children": [
{
"id": "N49",
"name": "Choose 12 Bagels",
"description": null,
"min_selection": "12",
"max_selection": "12",
"sel_dep": 1,
"type": "option group",
"children": [
{
"id": "N50",
"name": "Plain",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "12.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N51",
"name": "Salred",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "12.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N52",
"name": "Garlic",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "12.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N53",
"name": "Onion",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "12.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N54",
"name": "Everything",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "12.00",
"increment": "1.00",
"type": "option",
"children": []
},
{
"id": "N55",
"name": "Poppy",
"description": null,
"price": null,
"max_price": null,
"min_qty": "0.00",
"max_qty": "12.00",
"increment": "1.00",
"type": "option",
"children": []
}
]
}
]
},
{
"id": "N56",
"name": "Cream Cheese",
"description": null,
"min_qty": "0.25",
"max_qty": "25.00",
"price": "7.99",
"max_price": "7.99",
"increments": 0.25,
"qty_name_singular": "lb.",
"qty_name_plural": "lbs.",
"type": "item",
"children": []
},
]
}
]
}
GET /merchant/{merchant_id}/menu
Parameters
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
merchant_id | Integer | The id of the merchant from the Search endpoint. |
Optional Parameters | ||
item_only | 0/1 | If 1 is passed, then only items will be returned without any of their options. This will generally return faster, but you’ll have to make another API call to get the full list of options if the user views an item. |
hide_unavailable | 0/1 | If 1 is passed, then only the items that are currently available to order will be returned. For example: breakfast menu may have a schedule from 8:00am-11:00am, if you do a search at 2:00pm, the breakfast menu/items will NOT be returned if hide_unavailable is set to 1. |
Request Body
Do not supply a request body with this method.
Responses
Success
HTTP 200 OK
Property Name | Value | Description |
---|---|---|
schedule | Object[] | Array of schedules. Schedules are used when certain menus/items are only available during certain time windows, like in the case of breakfast menu. |
schedule.id | Integer | Id of this schedule. Menus/Items will reference schedules using this id. |
schedule.times | Object[] | The time ranges for the schedule over the next 7 days. Times are in UTC. |
warnings | Object[] | Some items require a disclaimer to be shown. There are two types, alcohol and tobacco. TODO: Get disclaimer text. |
warnings.items | String[] | the item IDs that these warnings apply to. |
menu | Entity[] | The array of menu entities. |
Invalid Merchant Id
{
"message": [
{ "code" : "no_rest",
"user_msg" : "Sorry, we weren't able to find the merchant."
},
]
}
This is returned when an invalid merchant id is passed.
HTTP 400 Bad Request
Item Request
{
"schedule": [],
"warnings": [],
"item": [
{
"id": "N2668",
"name": "Apple Juice",
"description": "",
"min_qty": 1,
"max_qty": 25,
"price": 3.95,
"max_price": 3.95,
"increment": 1,
"type": "item",
"children": []
}
]
}
Used to request a single item.
HTTP Request
GET /merchant/{merchant_id}/menu/{item_id}
Parameters
Parameter Name |Value |Description
-----------------------|-------|-----------
Required Parameters| |
merchant_id |Integer|The id of the merchant from the Search endpoint.
item_id |String |The item id which starts with ‘N’.
Request Body
Do not supply a request body with this method.
Responses
Success
HTTP 200 OK
Property Name | Value | Description |
---|---|---|
schedule | Object[] | Array of schedules. Schedules are used when certain menus/items are only available during certain time windows, like in the case of breakfast menu. |
schedule.id | Integer | Id of this schedule. Menus/Items will reference schedules using this id. |
schedule.times | Object[] | The time ranges for the schedule over the next 7 days. Times are in UTC. |
warnings | Object[] | Some items require a disclaimer to be shown. There are two types, alcohol and tobacco. TODO: Get disclaimer text. |
item | Entity[] | An single object array that contains an item entity. |
Invalid Item Id
{
"message": [
{
"code": "no_item",
"user_msg": "Item not found.",
"dev_msg": "Item not found."
}
]
}
This is returned when an invalid item id is passed.
HTTP 400 Bad Request
Customer
Customer Info
This endpoint returns basic customer information. This request requires an access token in the Authorization HTTP header.
HTTP Request
Success Response
{
"message": [],
"user": {
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "5555555555",
"delivery_points": 1000,
"life_time_delivery_points": 6000,
"user_id": 1234567,
"customer_id": 1345678,
"human_id": 1345678,
"roles": [ "USER" ],
"life_time_orders_count": 50,
"sms_notify": true,
"life_time_orders_count_per_vertical": {
"alcohol": 2,
"food": 40,
"groceries": 3,
"laundry": 5
},
"account_integrations": [],
"pending_updates": {
"to_email": null,
"to_phone": null,
"valid_until": false
},
"office_user": {
"name": "example company",
"role": "Staff"
},
"is_tax_exempt": false
},
"userAddress": {
"location_id": 7654321,
"label": "work",
"street": "1600 Pennsylvania Ave NW",
"city": "Washington",
"state": "DC",
"phone": "5555555555",
"zip_code": "20500",
"postal_code": "20500",
"cross_streets": null,
"unit_number": "",
"instructions": "",
"company": null,
"company_id": 1,
"longitude": -77.0371275,
"latitude": 38.897804,
"date_last_used": "2018-04-20T11:24:29+0000",
"default": false,
"editable_fields": [ "street", "city", "state" ]
},
"user_payments": {
"credit_balance": {
"id": 1065801,
"value": 0
},
"gift_cards": [
{
"id": 4111111,
"value": "10.00",
"type": "S",
"last_four": "ABCD"
}
],
"total_credit": 10
},
"third_party_auth": "",
"uid": ""
}
GET /customer/account
Request Parameters
There are no request parameters, but you must include an access token.
Bad Address Response
{
"message": [],
"user": {
"human_id": "231212",
"email": "grandmatillie@gmail.com",
"first_name": "Grandma",
"last_name": "Tillie"
}
}
You receive this response when all your input is valid, but we couldn’t verify your address against the USPS database.
HTTP 400 Bad Request
Property | Type | Description |
---|---|---|
user.human_id | String | Unique id of the user. |
user.email | String | The user’s email. |
user.first_name | String | User’s first name. |
user.last_name | String | User’s last name. |
Customer Payment Methods
Payment methods are required for placing an order. All requests require an access token in the Authorization HTTP header. See Authentication.
Get Credit Card Request
Response
{
"message": [],
"cards": [
{
"cc_id": "280394",
"type": "Visa",
"last_four": "5640",
"exp_month": 11,
"exp_year": 2012
},
{
"cc_id": "392321",
"type": "Visa",
"last_four": "5040",
"exp_month": 11,
"exp_year": 2015
},
{
"cc_id": "147021235",
"type": "American Express",
"last_four": "1201",
"exp_month": 5,
"exp_year": 2016
}
]
}
HTTP Request
GET /customer/cc
Parameters
Parameter Name | Type | Description |
---|---|---|
include_expired | true/false | Whether or not to include expired credit cards in the response. Defaults to false. |
Property Name | Type | Description |
---|---|---|
cards | Object[] | Array of credit card info. |
cards.cc_id | String | Unique identifier for this credit card. |
cards.type | String | Long description of credit card. |
cards.last_four | String | Last 4 digits of credit card. |
cards.exp_month | Integer | Expiration month of credit card. |
cards.exp_year | Integer | Expiration year of credit card. |
Customer Orders
View customer orders that have already been placed. All of these requests require an access token in the Authorization HTTP header.
View a single order
Response
{
"message": [],
"order": {
"order_id": 12107820,
"merchant_id": 67193,
"name": "Cafe Fresco",
"street": "1239 1ST AVE",
"city": "NEW YORK",
"state": "NY",
"zip_code": "10065",
"phone": "212-535-9030",
"confirmed": true,
"instructions": "",
"payment_method": "Deal",
"order_date": "2014-02-01T11:16:12-0500",
"delivery_date": "2014-02-01T11:16:12-0500",
"location_id": 1481165,
"latitude": 40.767302,
"longitude": -73.956324,
"discount": 0,
"delivery_fee": 0,
"tax": 1.97,
"subtotal": 22.2,
"tip": 3.33,
"total": 27.5,
"gift_card_amount_used": 0,
"promo_amount_used": 8,
"points_earned": 555,
"type": "delivery",
"cart": [
{
"id": "N2998",
"item_key": 1,
"name": "Two Eggs Sandwich",
"price": 4.25,
"quantity": 1,
"options": [
{
"id": "N3252",
"item_key": 1,
"name": "Egg Preparation",
"quantity": 1,
"options": [
{
"id": "N3258",
"item_key": 1,
"name": "Fried Over Medium",
"quantity": 1
}
]
},
{
"id": "N3253",
"item_key": 2,
"name": "Egg Sandwich Add Ons",
"quantity": 1,
"options": [
{
"id": "N3269",
"item_key": 1,
"name": "with Bacon",
"quantity": 1
}
]
},
{
"id": "N3254",
"item_key": 3,
"name": "Sandwich Preparation",
"quantity": 1,
"options": [
{
"id": "N3273",
"item_key": 1,
"name": "Sesame Bagel",
"quantity": 1
}
]
},
{
"id": "N3255",
"item_key": 4,
"name": "Breakfast Add Ons",
"quantity": 1
}
]
}
],
"favorite": false,
"favorite_name": null,
"vertical": {
"type": "R",
"name": "restaurant",
"label": "Restaurant"
}
}
}
Request
GET /customer/orders/recent/{order_id}
Parameters
Parameters | Values | Description |
---|---|---|
order_id | String | Unique id of the order. |
Property Name | Type | Description |
---|---|---|
order | Object[] | An object which contains the order details. |
order.order_id | Integer | Unique id for this order. |
order.merchant_id | Integer | Unique id of the merchant that this order was placed with. |
order.name | Integer | Name of the merchant. |
order.street | String | Street address of merchant. |
order.city | String | City of merchant. |
order.state | String | 2 character state of the merchant. |
order.zip | String | 5 digit zip of the merchant. |
order.phone | String | Phone number of merchant. |
order.confirmed | true | false |
order.instructions | String | Any special delivery/pickup instructions left by the user. |
order.payment_method | String | Description of the payment method used on the order. |
order_date | String | Time the order was placed in ISO 8601 format. |
delivery_date | String | Requested delivery time of the order in ISO 8601 format. If this is the same as order_date, it was an ASAP order. |
location_id | Integer | Unique id for the customer’s address. |
latitude | Double | Latitude of the location that the order is delivered to. |
longitude | Double | Longitude of the location that the order is delivered to. |
discount | Float | Dollar amount of the order that was discounted by the merchant. |
delivery_fee | Float | Dollar amount of the delivery_fee. |
tax | Float | Dollar amount of the tax. |
subtotal | Float | Dollar amount of the subtotal. |
tip | Float | Dollar amount of the tip. |
total | Float | Dollar amount of the total. |
gift_card_amount_used | Float | Dollar amount that was paid with a gift card. |
promo_amount_used | Float | Dollar amount that was paid with a delivery.com promotion. |
points_earned | Integer | How many delivery points were earned for this order. |
type | pickup | delivery |
favorite | true | false |
favorite_name | String | null |
vertical | Object | Information about the type of merchant this is. See merchant-search for a list of possible verticals. |
cart | Object[] | Array of ‘order entities’ (items, option_groups, options) that describe the contents of the order. The structure is similar to our menu entities. “ |
cart.id | String | ID of the entity. |
cart.item_key | Integer | The item’s index within the array of entities. |
cart.name | String | Name of the entity. |
cart.price | Float | Only on the top level entities (items). Not on options. Total price of the item, including selected options. |
cart.quantity | Float | What quantity of this entity. |
cart.options | Object[] | Array of child entities. Structure is the same as the ‘top-level entity’ except there is no price listed. |
View Order History
Response
{
"message": [],
"orders": [
{
"order_id": "12107820",
"merchant_id": "67193",
"name": "Cafe Fresco",
"confirmed": true,
"order_date": "2014-02-01T11:16:12-0500",
"delivery_date": "2014-02-01T11:16:12-0500",
"location_id": "1481165",
"total": 27.5,
"type": "delivery",
"favorite": false,
"favorite_name": null,
"vertical": {
"type": "R",
"name": "restaurant",
"label": "Restaurant"
}
},
{
"order_id": "12072307",
"merchant_id": "71843",
"name": "Salvo's Pizzabar",
"confirmed": true,
"order_date": "2014-01-26T18:43:30-0500",
"delivery_date": "2014-01-26T18:43:30-0500",
"location_id": "1481165",
"total": 30.34,
"type": "delivery",
"favorite": false,
"favorite_name": null,
"vertical": {
"type": "R",
"name": "restaurant",
"label": "Restaurant"
}
}
]
}
Request
GET /customer/orders/recent
Parameters
Property Name | Type | Description. |
---|---|---|
orders | Object[] | Array of order details. |
order.order_id | Integer | Unique id for this order. |
order.merchant_id | Integer | Unique id of the merchant that this order was placed with. |
order.name | Integer | Name of the merchant. |
order.confirmed | true | false |
order_date | String | Time the order was placed in ISO 8601 format. |
delivery_date | String | Requested delivery time of the order in ISO 8601 format. If this is the same as order_date, it was an ASAP order. |
location_id | Integer | Unique id for the customer’s address. |
total | Float | Dollar amount of the total. |
type | pickup | delivery |
favorite | true | false |
favorite_name | String | null |
vertical | Object | Information about the type of merchant this is. See merchant-search for a list of possible verticals. |
Re-order
Response
{
"message": [
],
"merchant_id": "752",
"url": {
"geo": null,
"merchant": null,
"geo_tag": "nyc",
"short_tag": "underground-pizza"
},
"location": {
"location_id": "1574911",
"street": "199 WATER ST",
"city": "NEW YORK",
"state": "NY",
"phone": "555-555-5555",
"zip_code": "10038",
"cross_streets": "Fulton Street",
"unit_number": "",
"company": "",
"building_id": "2580",
"latitude": "40.7068885740958600",
"longitude": "-74.0042710304260300"
}
}
Request
POST /customer/cart/reorder
Parameters
Parameters | Values | Description |
---|---|---|
order_id | String | Unique id of the order. |
Get Favorite Orders
Response
{
"message": [
],
"orders": [
{
"merchant_id": "752",
"merchant_name": "Underground Pizza",
"merchant_url": "underground-pizza",
"favorite_order_id": "521309",
"orders_id": "11988895",
"order_name": "",
"order_total": 78.39,
"order_date": "2014-04-04T13:18:44-0400",
"delivery_date": "2014-04-04T13:18:44-0400",
"integration_id": ""
}
]
}
Request
GET /api/customer/orders/favorite
Parameters
none
Add Favorite Order
Response
{
"message": [
{
"code": "favo_add_success",
"user_msg": "Order successfully added to favorites.",
"dev_msg": "Order successfully added to favorites."
}
]
}
Request
POST /api/customer/orders/favorite/{order_id}
Parameters
Parameters | Values | Description |
---|---|---|
order_name | String | Optional, a convenience name for the order |
Remove Favorite Order
Response
{
"message": [
{
"code": "favo_remove_success",
"user_msg": "Order successfully removed from favorites.",
"dev_msg": "Order successfully removed from favorites."
}
]
}
Request
DELETE /customer/orders/favorite/{order_id}
Parameters
none
Customer Addresses
A customer needs to have at least 1 address stored on their account to place an order. All requests require an access token in the Authorization HTTP header. Addresses are verified against the US Postal Service data..
Create Location
HTTP Request
{
"street" : "235 Park Ave S",
"unit_number" : "Floor 5",
"city" : "New York",
"state" : "NY",
"phone" : "555-555-5555",
"zip_code" : "10003",
"company" : "Delivery.com",
"cross_streets" : "85th and 1st",
}
POST /customer/location
Request Body
Property Name | Type | Notes |
---|---|---|
Required Properties | ||
street | String | Must be >= 5 characters. |
city | String | Must be >= 2 characters. |
state | String | Must be exactly 2 characters. |
zip_code | String | Must be exactly 5 characters. |
phone | String | The customer’s phone number at this location. Must be 10-12 characters. |
Optional Properties | ||
unit_number | String | Used for apartment number, suite, floor, etc. |
company | String | Sometimes there are multiple businesses on the same floor of a building. This is useful for the merchant in that case. |
cross_streets | String | Nearest major cross streets. |
Success Response
{
"message": [],
"location": {
"cross_streets": "Fulton Street",
"company": null,
"phone": "555-555-5555",
"unit_number": null,
"street": "199 WATER ST",
"city": "NEW YORK",
"state": "NY",
"zip_code": "10038",
"location_id": 1574911,
"longitude": "-74.0042710304260300",
"latitude": "40.7068885740958600"
}
}
HTTP 200 OK
If successful, the API returns you the location_id of the address you just inserted. This is required for the checkout API.
Bad Address Response
{
"message" : [
{ "code" : "bad_loc",
"user_msg" : "We could not find the address that you submitted. Please double check all the fields and try again.",
"dev_msg" : "Address was not verified.",
},
]
}
You receive this response when all your input is valid, but we couldn’t verify your address against the USPS database. HTTP 400 Bad Request
Invalid Request
{
"message" : [
{ "code" : "bad_street",
"field" : "street",
"user_msg" : "The street must be at least 2 characters.",
"dev_msg" : "The street must be at least 2 characters.",
},
{ "code" : "bad_city",
"field" : "city",
"user_msg" : "The city must be at least 2 characters.",
"dev_msg" : "The city must be at least 2 characters.",
},
{ "code" : "bad_state",
"field" : "state",
"user_msg" : "The state must be 2 characters.",
"dev_msg" : "The state must be 2 characters.",
},
{ "code" : "bad_zip_code",
"field" : "zip_code",
"user_msg" : "The zip code field must be 5 characters.",
"dev_msg" : "The zip code field must be 5 characters.",
},
{ "code" : "bad_phone",
"field" : "phone",
"user_msg" : "The phone must be at least 10 characters.",
"dev_msg" : "The phone must be at least 10 characters."
}
]
}
You receive this response when at least 1 of your input fields doesn’t pass our validation rules. HTTP 400 Bad Request
Update Location
HTTP Request
{
"unit_number": "Floor 3"
}
PUT /customer/location/{location_id}
Update location behaves similarly to Create Location except you have to pass the location_id as part of the URL and only the fields that need to be changed. In addition, there is one other possible response.
Request Body
Success Response
{
"message": [
{
"code": "loc_update_success",
"user_msg": "Address was successfully updated.",
"dev_msg": "Address was successfully updated."
}
],
"location": {
"street": "199 WATER ST",
"city": "NEW YORK",
"state": "NY",
"zip_code": "10038",
"longitude": "-74.0042710304260300",
"latitude": "40.7068885740958600",
"location_id": "1574907",
"phone": "555-555-5555",
"cross_streets": "Fulton Street",
"unit_number": "Floor 3",
"company": "Delivery.com"
}
}
HTTP 200 OK
Invalid Location Id
{
"message" : [
{ "code" : "bad_loc_id",
"user_msg" : "Sorry, but we weren't able to delete this address from your account.",
"dev_msg" : "Could no_cct find address for location id 8",
},
]
}
Delete Location
HTTP Request
DELETE /customer/location/{location_id}
This endpoint returns a HTTP 200 if successful, or a HTTP 400 if an invalid location_id is passed.
Get Locations
HTTP Request
{
"message": [],
"locations": [
{
"location_id": "952563",
"street": "232 PARK AVE S",
"city": "NEW YORK",
"state": "NY",
"phone": "555-555-5555",
"zip_code": "10003",
"cross_streets": "19th Street",
"unit_number": "",
"company": "",
"longitude": "-73.9883770000000000",
"latitude": "40.7375940000000000"
},
{
"location_id": "992053",
"street": "235 PARK S AVE",
"city": "NEW YORK",
"state": "NY",
"phone": "555-555-5555",
"zip_code": "10003",
"cross_streets": "19th street",
"unit_number": "floor 5",
"company": "",
"longitude": "-73.9879490000000000",
"latitude": "40.7377100000000000"
}
]
}
GET/customer/location/
Optional Parameters Sometimes you have a user’s address (including coordinates) from the user’s search results, but you don’t know if that user already has that address on their account. You can filter your results to a certain location by passing coordinates in. This also means you don’t need to ask the user for extra info (like phone number) if it’s already on the location stored on their account.
Name | Type | Description |
---|---|---|
latitude | Float | latitude that you want to filter results by. Only used if passed with a longitude. |
longitude | Float | longitude that you want to filter results by. Only used if passed with a latitude. |
Success Response
HTTP 200 OK
Property | Type | Description |
---|---|---|
locations | Customer Location[] | The locations on this customer’s account. |
Customer Cart
Overview
Cart state is maintained server-side, which frees up developers from the tricky task of client-side cart management. No call is needed to initiate a session; simply add an item for a given merchant ID and the cart can then be manipulated with the calls listed below.
Cart Session Modes
There are two different cart session modes for authenticated and guest users.
Authenticated User Cart
Authenticated user carts are identified with access tokens passed in the Authorization header. No special actions are necessary.
Guest Cart Guest carts are identified by the Guest-Token header, the value of which must be generated before initiating a cart session. Guest cart sessions can be integrated into authenticated user sessions by simply passing the Guest-Token header to the login and account creation endpoints, after which the converted carts can be accessed using the authenticated user flow described above.
Retrieve Contents
HTTP Request
Request Parameters
{
"order_type": "pickup",
"order_time": "2014-01-19T08:00:00-0500"
Response
{
"cart":[
{
"id":"E33",
"name":"Tuna Fish Salad Sandwich",
"quantity":3,
"type":"item",
"item_key":0,
"options":[
{
"id":"E34",
"name":"Choice of Bread",
"quantity":1,
"type":"option group",
"item_key":null,
"options":[
{
"id":"E41",
"name":"Cinnamon Raisin Bagel",
"quantity":1,
"type":"option",
"item_key":null,
"options":[
],
"item_label":"",
"price_compare_item":false,
"laundry_type":null,
"anonymous_id":null,
"images":[
]
}
],
"item_label":"",
"price_compare_item":false,
"laundry_type":null,
"anonymous_id":null,
"images":[
]
},
{
"id":"E44",
"name":"Choice of Sandwich Condiments\/Extras",
"quantity":1,
"type":"option group",
"item_key":null,
"options":[
{
"id":"E46",
"name":"Cheddar Cheese",
"quantity":1,
"type":"option",
"item_key":null,
"options":[
],
"item_label":"",
"price_compare_item":false,
"laundry_type":null,
"anonymous_id":null,
"images":[
]
}
],
"item_label":"",
"price_compare_item":false,
"laundry_type":null,
"anonymous_id":null,
"images":[
]
}
],
"item_label":"",
"price_compare_item":false,
"laundry_type":null,
"anonymous_id":null,
"images":[
],
"price":7.5
}
],
"item_count":3,
"subtotal":7.5,
"tax":0.79,
"total":14.09,
"discount":0,
"discount_percent":0,
"fees":[
{
"name":"Required Tip",
"value":1.35
},
{
"name":"City Bag Fee",
"value":0.23
},
{
"name":"Healthy SF Surcharge",
"value":1.54
},
{
"name":"Convenience Fee",
"value":0.93
},
{
"name":"Delivery Fee",
"value":1.75
}
],
"delivery_points":150,
"delivery_points_multiplier":1,
"time_updated":"2016-07-15T13:40:12-0400",
"asap":true,
"order_time":"2016-07-15T14:00:00-0400",
"laundry_pickup_times":[
],
"laundry_delivery_times":[
],
"minutes_left_for_asap_order":599,
"message":[
{
"code":"loc_invalid_range",
"user_msg":"The address Schenectady NY 12345 is out of the merchant's delivery range.",
"dev_msg":"The address Schenectady NY 12345 is out of the merchant's delivery range."
}
]
}
GET /customer/cart/{merchant_id}
Parameter Name | Type | Notes |
---|---|---|
Required Parameters | ||
order_type | String | Must be either ‘pickup’ or ‘delivery’ (Note: Items and Carts are never for pickup or for delivery only. The reason we ask for the type in all the cart operations is so we can calculate details about the cart – delivery fee for example.) |
Optional Parameters | ||
order_time | String | For future orders; must be ISO8601 format |
client_id | String | Required if passing a Guest-Token for unauthenticated users |
Required Parameters (Delivery Orders) | ||
zip | String | 5 characters |
city | String | |
state | String | |
latitude | Float | |
longitude | Float |
Success Response
HTTP 200 OK
Missing Delivery Address Response
{
"cart": null,
"item_count": 0,
"message": [
{
"field": "zip",
"code": "no_zip",
"user_msg": "The zip field is required.",
"dev_msg": "The zip field is required."
},
{
"field": "city",
"code": "no_city",
"user_msg": "The city field is required.",
"dev_msg": "The city field is required."
},
{
"field": "state",
"code": "no_state",
"user_msg": "The state field is required.",
"dev_msg": "The state field is required."
},
{
"field": "latitude",
"code": "no_latitude",
"user_msg": "The latitude field is required.",
"dev_msg": "The latitude field is required."
},
{
"field": "longitude",
"code": "no_longitude",
"user_msg": "The longitude field is required.",
"dev_msg": "The longitude field is required."
}
],
"subtotal": 0,
"tax": 0,
"total": 0,
"discount": 0,
"fees": [
],
"order_time": "2014-02-09T23:45:00-0500",
"asap": true,
"order_type": "delivery"
}
HTTP 400 Bad Request
Add Item(s)
HTTP Request
Add One Item
{
"order_type":"delivery",
"order_time":"ASAP",
"item":{
"item_id":"E761",
"item_qty":2,
"option_qty":{
"E114":1,
"E428":1,
"E763":1
},
"item_label":"",
"instructions":""
},
"client_id":"MDlkMzY3Nzg3MjU1ZjRkNmY4OWZjNDA0NjBjMTI0MWZl"
}
Add Multiple items
{
"order_type": "delivery",
"instructions": "Some instructions",
"items":[
{
"item_id":"E354",
"item_qty":1,
"option_qty":{
"E4":1,
"E19":1,
"E203":1
},
"item_label":"",
"instructions":""
},
{
"item_id":"E145",
"item_qty":1,
"option_qty":{
"E69":1,
"E134":1,
"E137":1,
"E143":1
},
"item_label":"",
"instructions":""
}
],
"client_id": "NDY4NDAzYzViYmI0YWM0NTM3NTJmYzhmZWJkMWQwMWZi"
}
POST /customer/cart/{merchant_id}
Property Name | Type | Notes |
---|---|---|
Required Parameters | ||
item | Item | Use this param to add one item to the cart. (To add multiple items, use the following one) |
items | Array of Item | Use this param to add multiple items to the cart at once. (To add one item, use the above one) |
order_type | String | Must be either ‘pickup’ or ‘delivery’ (Note: Items are never for pickup or for delivery only. The reason we ask for the type in all the cart operations is so we can calculate details about the cart – delivery fee for example.) |
Optional Parameters | ||
order_time | String | For future orders; must be ISO8601 format |
instructions | String | Special requests for this particular item |
client_id | String | Required if passing a Guest-Token for unauthenticated users |
Success Response
{
"item_id": "N9",
"item_qty": 1,
"option_qty": {
"N17": 1
},
"instructions": "Item instructions"
}
HTTP 200 OK
The response is identical to Retrieve Content endpoint.
Modify an Item
Request Body
{
"order_type":"delivery",
"order_time":"ASAP",
"item":{
"item_id":"E33",
"item_qty":2,
"option_qty":{
"E41":1,
"E46":1
},
"item_label":""
},
"cart_index":0,
"client_id":"MDlkMzY3Nzg3MjU1ZjRkNmY4OWZjNDA0NjBjMTI0MWZl"
}
HTTP Request
PUT /customer/cart/{merchant_id}
Property Name | Type | Notes |
---|---|---|
Required Parameters | ||
cart_index | Integer | The cart item’s item_key value to remove. |
item | Item | The cart item to edit |
order_type | String | Must be either ‘pickup’ or ‘delivery’ (Note: Items are never for pickup or for delivery only. The reason we ask for the type in all the cart operations is so we can calculate details about the cart – delivery fee for example.) |
Optional Parameters | ||
order_time | String | For future orders; must be ISO8601 format |
client_id | String | Required if passing a Guest-Token for unauthenticated users |
Success response
HTTP 200 OK
The response is identical to Retrieve Content endpoint.
Incorrect Cart Index Response
{
"message": [
{
"code": "cart_index_not_found",
"user_msg": "The item was not found in your cart.",
"dev_msg": "Cart index ($cart_index) not found."
}
],
"subtotal": 27,
"tax": 2.4,
"item_key": 0,
"item_count": 3,
"order_time": "2014-02-07T18:45:00-0500"
}
HTTP 400 Bad Request
Clear Cart / Remove an Item
Request Body
{
"cart_index": 0
}
HTTP Request
DELETE /customer/cart/{merchant_id}
Property Name | Type | Notes |
---|---|---|
Optional Parameters | ||
cart_index | Integer | The cart item’s item_key value to remove. Only removes specific item; otherwise the cart will be cleared. |
client_id | String | Required if passing a Guest-Token for unauthenticated users |
Success Response
HTTP 200 OK
The response is identical to Retrieve Content endpoint.
Generate a Guest Token
HTTP Request
GET /customer/auth/guest
Request Params
{
"client_id": "NDY4NDAzYzViYmI0YWM0NTM3NTJmYzhmZWJkMWQwMWZi"
}
Success Response
HTTP 200 OK
{
"Guest-Token": "f528764d624db129b32c21fbca0cb8d652f8625c459096.60225085"
}
Checkout
Customer Checkout
Overview
Checkout is the final endpoint in the customer order flow. It is used to retrieve available payment options and to book orders.
Get Payments
Request Parameters
{
"order_type": "pickup",
"order_time": "2014-01-19T08:00:00-0500"
}
HTTP Request
GET /customer/cart/{merchant_id}/checkout
Property Name | Type | Notes |
---|---|---|
Required Properties | ||
order_time | String | Must be ISO8601 format |
order_type | String | Must be either ‘pickup’ or ‘delivery’ |
Success Response
{
"message":[
],
"allowed_payment_methods":[
"cash",
"credit_balance",
"credit_card",
"gift_code",
"promo",
"nonce_androidpay",
"nonce_applepay",
"nonce_paypal",
"nonce_venmo",
"visa_checkout"
],
"disallowed_payment_methods":[
],
"payment_methods":{
"credit_card":[
{
"last_four":"3214",
"cc_type":"Visa",
"id":"123456",
"exp_month":"6",
"exp_year":"2018",
"last_used":null
}
],
"name":"Test Merchant 20130315",
"merchant_id":13431,
"cash":{
"max":65
},
"promo":[
{
"name":"Employee Deal",
"id":35363,
"minimum":0,
"expires":"2020-06-28T23:59:00-0400",
"code":null,
"first_order":false,
"total_uses":null,
"limitType":null,
"valueLimit":null,
"checkout_message":"Note that the receipt from the merchant will not reflect the discount.",
"value":10,
"reward":"percent_off",
"customer_group":"all",
"is_vertical_specific":false,
"verticals":null,
"is_merchant_specific":false,
"merchants":[
],
"is_selectable":1,
"selectable_message":null,
"selectable_reason":null
},
{
"name":"VisaCheckout",
"id":1154227,
"minimum":5.01,
"expires":"2016-10-01T23:59:00-0400",
"code":null,
"first_order":false,
"total_uses":1,
"limitType":null,
"valueLimit":null,
"checkout_message":"Receive $5.00 off your order when use VisaCheckout.",
"value":5,
"reward":"dollar_off",
"customer_group":"all",
"is_vertical_specific":false,
"verticals":null,
"is_merchant_specific":false,
"merchants":[
],
"is_selectable":1,
"selectable_message":null,
"selectable_reason":null
},
{
"name":"$5 off for Pander Users",
"id":1424949,
"minimum":15,
"expires":"2017-01-03T00:00:00-0500",
"code":null,
"first_order":false,
"total_uses":1,
"limitType":null,
"valueLimit":null,
"checkout_message":"",
"value":5,
"reward":"dollar_off",
"customer_group":"all",
"is_vertical_specific":false,
"verticals":null,
"is_merchant_specific":false,
"merchants":[
],
"is_selectable":0,
"selectable_message":"The selected deal does not apply for this platform.",
"selectable_reason":"PLATFORM_MISMATCH"
}
],
"gift_code":[
{
"value":77.05,
"last_four":"4JKT",
"id":"3806031"
},
{
"value":31.12,
"last_four":"F726",
"id":"3826096"
}
],
"credit_balance":[
],
"paypal":true
},
"concur":false,
"sms_notify":false,
"has_used_visa_checkout":true
}
HTTP 200 OK
Place Order – Authenticated Users
HTTP Request
POST /customer/cart/{merchant_id}/checkout
Request Body
{
"order_type":"delivery",
"order_time":"ASAP",
"location_id":3276032,
"payments":[
{
"type":"credit_card",
"id":1
}
],
"instructions":"",
"save_instructions":false,
"sms_notify":false,
"extra_options":{
"mute_concur":true
},
"phone_number":"6464030033",
"tip":"0.00",
"merchant_id":"13431",
"client_id":"MDlkMzY3Nzg3MjU1ZjRkNmY4OWZjNDA0NjBjMTI0MWZl"
}
Request Body Split Payment
{
"tip": 1.00,
"location_id": 10,
"uhau_id" : 12345,
"instructions": "Don't burn my toast again, grandma!",
"payments": [
{
"type": "credit_card",
"id": 1,
"amount": 5.00
},
{
"type": "credit_card",
"id": 2,
"amount": 10.00
}
],
"order_type": "delivery",
"order_time": "2014-01-19T08:00:00-0500"
}
You can split an order among multiple credit cards. A split payment can only be made among credit cards. Gift cards and promos cannot be applied. Other than the amount field, the call is identical to the standard checkout api call. The amounts must add up to the order total, including tip. Note: if you don’t wish a do a split payment order the amount field should not be present.
Property Name | Type | Notes |
---|---|---|
Required Properties | ||
order_type | String | Must be either ‘pickup’ or ‘delivery’ |
payments | PaymentType[] | |
location_id | int | Required ONLY for delivery orders |
Optional Properties | ||
tip | Double | Generally used for delivery orders only |
order_time | String | Must be ISO8601 format |
instructions | String | Maximum 100 characters |
uhau_id | int | User Hear About Us ID. Please use this to associate the order to your account. |
sms_notify | Boolean | Whether to send the customer an SMS when their order is confirmed by the merchant |
Payment Types Array
This array contains objects that specify which payment methods will be used to pay for an order. The id and type for each object must correspond to the payment_methods object properties returned in the GET response. Omit payment types from the array that won’t be used to pay for the order.
Payment Type | Notes |
---|
cash Doesn’t require an an id attribute credit_card | | promo | | gift_code | | nonce | | credit_balance |Delivery.com’s user promotion credit
SPECIAL CASH ORDER CONSIDERATIONS
- Cash can be applied to an order only if the order total is less than or equal to payment_methods.cash.max in the GET response.
- Cash can NOT be combined with any other payment method
EXAMPLE CONFIGURATIONS
//Cash order
[
{
"type": "cash"
}
]
//Nonce order
[
{
"type":"nonce",
"value": "bb08093c-1ewe-47as-9asd-063508a11f67"
}
]
//Credit card and promo payment combination array
[
{
"type": "credit_card",
"id": 1
},
{
"type": "promo",
"id": 10
}
]
Success Response
HTTP 200 OK
{
"code": "ok",
"delivery_points": 1000,
"order_id": 123456,
"user_msg": "Order successfully placed.",
"dev_msg": "Order successfully placed."
}
Error Responses
Merchant Not Found Response
{
"message": [
{
"code": "no_rest",
"user_msg": "Merchant not found.",
"dev_msg": "Merchant not found."
}
]
}
You receive this response when no merchant exists for merchant_id or the merchant is inactive.
HTTP 400 Bad Request
Bad Order Time Response
{
"message": [
{
"code": "chkout_error",
"user_msg": "There was a problem with checkout.",
"dev_msg": "There was a problem with checkout."
},
{
"code": "cart_invalid_future",
"user_msg": "Order time too far into the future.",
"dev_msg": "Order time too far into the future."
},
{
"code": "cart_invalid_time",
"user_msg": "Order time can not be in the past.",
"dev_msg": "Order time can not be in the past."
},
{
"code": "cart_time_unavailabile",
"user_msg": "Merchant is closed at the requested time.",
"dev_msg": "Merchant is closed at the requested time."
},
{
"code": "ckout_asap_unavailable",
"user_msg": "he merchant is not currently available for ordering. Please select a future order time.",
"dev_msg": "he merchant is not currently available for ordering. Please select a future order time."
}
]
}
You receive this response for invalid order times.
HTTP 400 Bad Request
More Checkout Error Response
HTTP 400 Bad Request
You receive this response when the order subtotal doesn’t meet the minimum.
{
"message": [
{
"code": "ckout_min_not_met",
"user_msg": "Subtotal minimum does not meet $:minimum.",
"dev_msg": "Subtotal minimum does not meet $:minimum."
}
]
}
You receive this response when you are using a location id that is out of service range.
{
"message": [
{
"code": "ckout_bad_loc",
"user_msg": "Your address is not currently serviceable.",
"dev_msg": "Your address is not currently serviceable."
}
]
}
You receive this response when there is already a checkout process for this same order.
{
"message": [
{
"code": "ckout_in_progress",
"user_msg": "Checkout is in progress, please wait.",
"dev_msg": "Checkout is in progress, please wait."
}
]
}
You receive this response when you’re trying to checkout an empty cart.
{
"message": [
{
"code": "ckout_empty_cart",
"user_msg": "Your cart is empty. Please add some items before checking out.",
"dev_msg": "Your cart is empty. Please add some items before checking out."
}
]
}
You receive this response when you’re trying to checkout using cash as a payment method, but that merchant doesn’t accept cash order up to that amount.
{
"message": [
{
"code": "cash_not_allowed_merch_max",
"user_msg": ":merchant_name only accepts cash orders up to $ :max_price. Please use a different payment method or remove some items from your bag.",
"dev_msg": ":merchant_name only accepts cash orders up to $ :max_price. Please use a different payment method or remove some items from your bag."
}
]
}
Error Responses – Split Payment
Card Declined Error
You will receive this error if one of the cards is declined for any reason.
{
"message": [
{
"code": "cc_number_declined",
"user_msg": "Sorry, that credit card was declined. Please try re-entering the card details, since the expiration date or zip code may have changed, or use a different card.",
"dev_msg": "Expired Card on card:2"
}
]
}
Order Balance Not Met Error
You will receive this error if the amounts on the cards don’t add up to the order total.
{
"message": [
{
"code": "balance_not_met",
"user_msg": "The order balance has not been met.",
"dev_msg": "The order balance has not been met"
}
]
}
Missing amount error
You will receive this error of you don’t provide amounts for every payment type.
{
"message": [
{
"code": "missing_amount_values",
"user_msg": "messages.missing_amount_values",
"dev_msg": "Missing amount parameter for some payments"
}
]
}
Place Order – Guest Users
IMPORTANT : THIS API CALL TAKES A GUEST TOKEN RATHER THAN AN AUTHORIZATION TOKEN
HTTP Request
Request Body
{
"order_type": "delivery",
"order_time":" ASAP",
"street": "199 Water St",
"city": "New York",
"state": "NY",
"zip_code": "10038",
"unit": "Apt 300",
"payments":[
{
"type":"credit_card",
"card":{
"cc_number":"4111111111111111",
"exp_year":"2024",
"exp_month":"08",
"cvv":"123",
"billing_zip":"11223",
"save":false
}
}
],
"instructions":"",
"sms_notify":false,
"isOptingIn" : true,
"phone_number":"2125551212",
"tip":"3.90",
"merchant_id":"69391",
"first_name":"sa",
"last_name":"yo",
"email":"sa@yo.com",
"client_id":"xxxxxxxxxxxxxxxx",
"uhau_id" : 12345
}
POST /guest/cart/{merchant_id}/checkout
Property Name | Type | Notes |
---|---|---|
Required Properties | ||
order_type | String | Must be either ‘pickup’ or ‘delivery’ |
payments | PaymentType[] | |
phone_number | String | User’s phone number as 10 character string |
first_name | String | User’s first name |
last_name | String | User’s last name |
String | User’s email address | |
Optional Properties | ||
tip | Double | Generally used for delivery orders only |
order_time | String | Must be ISO8601 format |
street | String | User’s street address (Required for delivery orders) |
city | String | User’s city (Required for delivery orders) |
state | String | User’s state as a 2 character string (Required for delivery orders) |
zip_code | String | User’s city (Required for delivery orders) |
unit | String | User’s apartment/unit number |
instructions | String | Maximum 100 characters |
uhau_id | int | User Hear About Us ID. Please use this to associate the order to your account. |
sms_notify | Boolean | Whether to send the customer an SMS when their order is confirmed by the merchant |
isOptingIn | Boolean | Whether to allow delivery.com to send customer promotion and marketing emails |
Success Response
{
"code": "ok",
"delivery_points": 1000,
"order_id": 123456,
"user_msg": "Order successfully placed.",
"dev_msg": "Order successfully placed."
}
HTTP 200 OK
User Login & Account Creation
delivery.com APIs use the OAuth 2.0 protocol for authentication and authorization. We recommend using an OAuth 2.0 library to interact with the API. For more information, see recommended client libraries. We also use a similar flow to OAuth to handle user account creation and user payment information.
Access public resources
For public resources like search, you simply need to include your client_id as a GET parameter. You can obtain a client_id by signing up.
Accessing protected resources
API calls that provide access to user information require an access token. The sequence for obtaining an access token is described below.
Your application redirects a browser to a delivery.com URL with a set of parameters that indicate the requested access. The user logs in and consents and their browser is redirected back to the redirect_uri with an authorization code. Your application exchanges that code (along with your client_id and client_secret) for an access token. Your application uses the access token to make API calls. webflow
User Login
This is not an API endpoint, but a web address to open in the client’s browser.
Request
GET /third_party/authorize
Parameters
Parameters | Values | Description |
---|---|---|
client_id | Your application’s Client Id.You receive this when you sign up. | Identifies which client is making the request. |
redirect_uri | One of the redirect_uri values listed on your account page. | Determines where the response is sent. The value of this parameter must exactly match one of the values registered for your app (including the http or https scheme, case, and trailing ‘/’). |
response_type | ‘code’ | Specifies that you want an access code returned. |
scope | ‘global’ | This specifies what permissions you’re requesting from the user. As of now, we only have one permission. |
state | Any string | This is for any state that your app needs to keep track of. This will be returned to you as a parameter on your redirect uri. |
guest_token | String | Optional. Passing the Guest-Token header value will copy a guest cart to the logged in user’s session cart. See the Customer Cart. |
Handling the response
We redirect to {redirect_uri}.
Error Response:
{redirect_uri}?error=access_denied&state={state}
An authorization code:
{redirect_uri}?code={authorization_code}&state={state}
User Account Creation
This is not an API endpoint, but a web address to open in the client’s browser. The delivery.com login page also allows the user to create an account, so you don’t need to give the user direct access to the create account page.
URL
GET /third_party/account/create
Parameters
Parameters | Values | Description |
---|---|---|
client_id | Your application’s Client Id.You receive this when you sign up. | Identifies which client is making the request. |
redirect_uri | One of the redirect_uri values listed on your account page. | Determines where the response is sent. The value of this parameter must exactly match one of the values registered for your app (including the http or https scheme, case, and trailing ‘/’). |
response_type | ‘code’ | Specifies that you want an access code returned. |
scope | ‘global’ | This specifies what permissions you’re requesting from the user. As of now, we only have one permission. |
state | Any string | This is for any state that your app needs to keep track of. This will be returned to you as a parameter on your redirect uri. Possible uses include redirecting the user to the proper page in your app. |
guest_token | String | Optional. Passing the Guest-Token header value will copy a guest cart to the logged in user’s session cart. See the Customer Cart. |
Handling the Response
The response is handled the same way as User Login.
Obtaining Access Tokens
{
"access_token": "xBUhbB1ESzhKLidYR4q98RmSitGu7tD9lhkw0EKA",
"token_type": "bearer",
"expires": 1391014905,
"expires_in": 3600,
"refresh_token": "a3Z55n5hP09hCVyLV6NlNwQzXl9RLuz1dXF4yQUv"
}
Returns OAuth access token. Make sure to store the refresh token for later.
HTTP Request
POST /third_party/access_token
Parameters
Parameters | Values | Description |
---|---|---|
Required | ||
client_id | Your application’s Client Id.You receive this when you sign up. | Identifies which client is making the request. |
redirect_uri | One of the redirect_uri values listed on your account page. | Determines where the response is sent. The value of this parameter must exactly match one of the values registered for your app (including the http or https scheme, case, and trailing ‘/’). |
grant_type | authorization_code / refresh_token | If you’re using a refresh_token, use refresh_token. Otherwise select authorization_code. |
client_secret | Your application’s client secret | The secret listed on your account page. |
code | String | The code returned by GET /api/third_party/authorize |
Optional | ||
refresh_token | String | Your refresh token that you obtained from your original access token request. |
Property Name | Type | Description |
---|---|---|
access_token | String | This is the token you submit with any API requests that require it. You must include it in the Authorization HTTP header. |
refresh_token | String | A token that may be used to obtain a new access token. Refresh tokens are valid until the user revokes access. |
token_type | Bearer | The type of token, which will always be bearer at the moment. |
expires_in | Integer | How long until this token expires, in seconds. |
expires | Long | The point in time that this token expires, in Unix Epoch Time. |
Refresh Access Tokens
Request
{
"client_id": "xBUhbB1ESzhKLidYR4q98RmSitGu7tD9lhkw0EKA",
"client_secret": "aaUhbB1ESzhKLidYR4q98RmSitGu7tD9lhkw0EKA",
"grant_type": "refresh_token",
"refresh_token": "a3Z55n5hP09hCVyLV6NlNwQzXl9RLuz1dXF4yQUv"
}
Response
{
"access_token": "XQ1evP0u4WpM763WQ8Zll5Z7h8oOOZAJDsJeDrfa",
"token_type": "bearer",
"expires": 1485382344,
"expires_in": 7776000
}
Returns new OAuth access token. Refresh token keeps the same.
HTTP Request
POST /third_party/refresh_token
Parameters
Parameters | Values | Description |
---|---|---|
Required | ||
client_id | String | Your application’s client ID |
client_secret | String | Your application’s client secret |
grant_type | String | refresh_token |
refresh_token | String | You will get refresh token from the last time you obtain an access token. |
User: Login via Password Flow
Login a user into their delivery.com account.
HTTP Request
Response
{
"access_token": "oDTUN25CLWyELpFKeWE0pHxMKjABCDEFGHIJKLMNO",
"token_type": "bearer",
"expires": 1470677249,
"expires_in": 7776000,
"refresh_token": "H5LnFUHVPUbnDDNoZPKBsCABCDEFGHIJKLMNOu",
"user": {
"email": "superman@delivery.com",
"first_name": "Clark",
"last_name": "Kent",
"delivery_points": 2450,
"life_time_delivery_points": 2450,
"customer_id": 13880***,
"human_id": 138****,
"roles": [
"USER",
],
"life_time_orders_count": 2,
"sms_notify": true,
"life_time_orders_count_per_vertical": {
"alcohol": 4,
"food": 0,
"groceries": 0,
"laundry": 0
},
"account_integrations": []
},
"userAddress": {
"location_id": 3048802,
"street": "1001 Avenue of the Americas",
"city": "New York",
"state": "NY",
"phone": "6097317150",
"zip_code": "10018",
"cross_streets": null,
"unit_number": "Floor 15 / Delivery.com",
"instructions": "",
"company": null,
"longitude": -73.986455,
"latitude": 40.751824,
"date_last_used": "2016-04-29T16:33:23+0000"
},
"user_payments": {
"credit_balance": {
"id": null,
"value": 0
},
"gift_cards": [],
"total_credit": 0
},
"third_party_auth": "",
"uid": ""
}
POST /customer/auth?
Resource Information
Parameter | Value |
---|---|
Response Format | JSON |
Authentication | password flow – client_id AND client_secret |
Rate Limited. | Yes |
AUTHENTICATION
This endpoint uses password flow. Your API partner account must have been granted password flow authentication. All API partners are strongly encouraged to [apply for password flow(#authentication)].
Pass in both the client_id and client_secret. View your API credentials by logging into your API Partner Account.
Example Request
https://api.delivery.com/customer/auth?username={username}@delivery.com&password={password}&grant_type=password&client_id={client_id}&client_secret={client_secret}&scope=global
You will need to update the parameters accordingly.
Parameters
All parameter keys should be lowercase; parameter values should all be UTF-8 and URL-encoded.
Parameter Name | Type | Description |
---|---|---|
Required Parameters | ||
username | string | Email address of user logging in. |
password | string | Password of user logging in. |
grant_type | string | Set to password. |
client_id | string | Api client_id string |
client_secret | string | Api client_secret string |
scope | string | Set to global. This is required – otherwise oauth authentication will fail. |
Credit Card
Add Credit Card
Add Credit Card
- This is not an API endpoint, but a web address to open in the client’s browser. It follows a similar flow to our OAuth 2.0 style authentication.
- Steps
- Send the user’s broswer to
/third_party/credit_card/add
- After the user adds a credit card, the browser will redirect back to the redirect_uri that you specify.
- View the user’s updated list of payment methods using
GET /customer/cc
- Send the user’s broswer to
REQUEST
/third_party/credit_card/add
PARAMETERS
Parameters | Values | Description |
---|---|---|
client_id | Your application’s Client Id.You receive this when you sign up | Required – Identifies which client is making the request. |
redirect_uri | One of the redirect_uri values listed on your account page | Required – Determines where the response is sent. The value of this parameter must exactly match one of the values registered for your app (including the http or https scheme, case, and trailing ‘/’). |
response_type | code | Required – Specifies that you want an access code returned. |
scope | global | Required – This specifies that you are requesting global permission. |
state | Any string | Optional. This is an optional paramter that you can pass in. The api will return this parameter on redirect back to your request_uri. |
HANDLING THE RESPONSE
We redirect to the redirect_uri that you pass in.
EXAMPLE REQUEST
https://api.delivery.com/api/third_party/credit_card/add?client_id={client_id}&redirect_uri={request_uri}&response_type=code&scope=global
Make sure to change client_id and request_uri to your api parameters.
Menu
Entities
{
"merchantId" : 1234,
"entities" : [
{
"description": "Items of each type are represented here.",
"alcohol": 0,
"tobacco": 0,
"type": "SubMenu",
"scheduleIds": [1],
"name": "Lunch Menu"
},
{
"type": "Item",
"price": 6.99,
"alcohol": 0,
"tobacco": 0,
"name": "Lunch Box",
"description": "The item description"
}
]
}
There are a number of menu element types (called “entities”), each with their own properties:
All | ||
---|---|---|
name | string | Required – The name to display |
description | string | A short description |
hidden | boolean | Used for temporarily removing an element from the menu |
type | string | Identifies the type of the entity (SubMenu, Item, etc) |
thirdPartyId | string | An identifier for your use, can be used for mapping between our systems |
SubMenu | ||
scheduleIds | integer[] | List of schedule ids that apply to the SubMenu |
alcohol | integer | Indicates if it’s children should present an alcohol warning (false => 0, true =>1) |
tobacco | integer | Indicates if it’s children should present a tobacco warning (false => 0, true =>1) |
Item | ||
scheduleIds | integer[] | List of schedule ids that apply to the Item |
alcohol | integer | Indicates if the Item should present an alcohol warning (false => 0, true =>1) |
tobacco | integer | Indicates if the Item should present a tobacco warning (false => 0, true =>1) |
price | float | Required – The price of the item, if set to 0 a price group must be linked |
qtyIncrements | float | Typically 1, determines the increments in which the quantity is selected: a value of 3 would mean the quantity options would be 3,5,9,etc |
qtyMin | float | Typically 1 |
qtyMax | float | Typically 25, the maximum number of the item that can be order at once |
qtyNameSingular | string | Displayed by the quantity when quantity is singular, ex: 1 lb. |
qtyNameSingular | string | Displayed by the quantity when quantity is plural, ex: 5 lbs. |
Option | ||
price | float | The price of the option |
qtyIncrements | float | Typically 1, determines the increments in which the quantity is selected: a value of 3 would mean the quantity options would be 3,5,9,etc |
qtyMin | float | Typically 0, when greater than 0 the option is required |
qtyMax | float | Varies based on OptionGroup selection type, for all but ‘quantity’ it will default to 1. For ‘quantity’, this determine the max amount of that option that can be selected. |
qtyNameSingular | string | Displayed by the quantity when quantity is singular, ex: 1 lb. |
qtyNameSingular | string | Displayed by the quantity when quantity is plural, ex: 5 lbs. |
OptionGroup | ||
selectionType | radio | check |
selectionType: | radio | The selection group will be a radio, the user must select exactly 1 option of quantity 1 |
selectionType: | check | The selection group will be a set of check boxes, the user selects between the min and max selections – each option of quantity 1 |
selectionType: | quantity | The selection group will be a set of dropdowns, the user selections a number of options up to the max selection – each option quantity can be up to the option’s max quantity – the total quantity of the options should be less than the max selections and greater than the min selections |
selectionType: | upToOne | The selection group will be a set of check boxes, the user may select up to one option of quantity 1 |
selectionsMin | integer | The minimum number of selections required, this accounts for quantity as well |
selectionsMax | integer | The maximum number of selections required, this accounts for quantity as well |
selectionDepends | boolean | Can be used with type quantity. Typically used for catering, this changes how selections min and max relate with item quantity. E.g. If a user orders 3 orders of 12 sandwiches: When this is false, the user selects 12 sandwiches that selection will be tripled. When this is true, the user selects 36 sandwiches. |
PriceGroup | Effectively a radio option group | |
None | N/A | All values are pre-set for this entity type except for name and description |
Image | ||
url | string | The url the image file is located. This will be downloaded and hosted on our server |
Each entity type, except Image, can have any number of children. There are rules for which entities each can have as children:
Entity | Valid Children |
---|---|
SubMenu | Either other SubMenus or Items, not both |
Item | Up to 1 PriceGroup, Up to 1 Image, Any number of OptionGroups |
OptionGroup | Any number of Options |
PriceGroup | Any number of Options |
Option | Up to 1 PriceGroup, Up to 1 Image, Any number of OptionGroups |
Image | None |
Each entity type has a general purpose. A SubMenu is used for grouping Items or other SubMenus. Items are actual dishes or standalone beverages. OptionGroups are used to provide options such as toppings, sides, or drinks. PriceGroups vary conceptually from Optiongroups, the purpose is to allow a change in price of the parent.
PriceGroup example: A pizza has 3 available sizes: small, medium, and large. The choice in size influences the price of the parent.
You should only use PriceGroup over OptionGroup in this type of situation. In the data, your item price may either be 0 with the lowest PriceGroup option being the lowest price available, or you may price your item at the lowest price and have a price of 0 on your smallest option in the PriceGroup.
When building a menu, there are a number of calls to be made. First, if there are any schedules linked to an entity, that should be created first so that you may pass the scheduleId with the entity. You can find information on the menu schedule calls here. Second, submit all entities for the menu, multiple entities can be submitted in a single call. Last, submit the links between the entities. This can be done in stages or all at once. We also provide a call that allows you to submit a full menu structure.
The calls to create, update, and delete individual entities are as follows:
When creating an entity, you may include a parentId in the entity object as a shortcut to making a second call to create the link.
POST /merchant/admin/menu
Entity ids
{"entityIds": [1,2]}
The entity ids will be returned in the order they were created. In case of failure, the message will include the full entity received with the relevant problem.
Update entities
{
"merchantId" : 1234,
"entities" : [
{
"type": "SubMenu",
"id": 1,
"name": "Renamed Menu",
},
{
"type": "Item",
"id": 2,
"name": "Renamed Item",
}
]
}
To make updates to entities, the id value is required along with the type.
PUT /merchant/admin/menu
Delete entities
Delete calls simply require the entity ids in a comma separated list:
DELETE /merchant/admin/menu?merchantId=1234&entityIds=1,2
Deletion of an entire menu should rarely be necessary, as changes should be handled via updates. If you require a removal of an entire menu, please contact your account manager to discuss the issue.
Link objects
{
"merchantId" : 1234,
"links" : [
{
"parentId": null,
"childId": 1
},
{
"parentId": 1,
"childId": 2,
"displayOrder": 4
}
]
}
{
"merchantId" : 1234,
"links" : [
{
"parentId": null,
"childId": 1,
"displayOrder": 1
},
{
"parentId": 1,
"childId": 2,
"displayOrder": 2
}
]
}
{
"merchantId" : 1234,
"links" : [
{
"parentId": null,
"childId": 1
},
{
"parentId": 1,
"childId": 2
}
]
}
Once you have your entities created, you’ll need to link them together to form a menu tree. The link calls accept an array of link objects:
Property Name | Type | Notes |
---|---|---|
parentId | integer | null |
childId | integer | Required – The id of the child entity |
displayOrder | integer | Determines the display order under the parent. If left empty, the id is used to determine the order. Any entity with a display order of any value will come before entities with no value. |
POST /merchant/admin/menu/link
Ids are not given for links, to reference them for update and delete, you should use the parent and child id. You can not update the parent or child id. For links, the only value that can be edited is ‘displayOrder’.
PUT /merchant/admin/menu/link
DELETE /merchant/admin/menu/link
GET /merchant/admin/menu?merchantId=
Response:
{
"schedule":[
{
"id":1,
"name":"Lunch Specials",
"hours":[
{
"id":1,
"day":1,
"startTime":"11:30",
"endTime":"14:30"
},
{
"id":2,
"day":2,
"startTime":"11:30",
"endTime":"14:30"
},
{
"id":3,
"day":3,
"startTime":"11:30",
"endTime":"14:30"
},
{
"id":4,
"day":4,
"startTime":"11:30",
"endTime":"14:30"
},
{
"id":5,
"day":5,
"startTime":"11:30",
"endTime":"14:30"
}
]
}
],
"menu":[
{
"description":"Items of each type are represented here.",
"alcohol":false,
"tobacco":false,
"type":"SubMenu",
"scheduleIds":[
1
],
"name":"Test Menu",
"children":[
{
"type":"Item",
"price":6.99,
"qtyIncrements":1,
"qtyMin":1,
"qtyMax":25,
"qtyNameSingular":"",
"qtyNamePlural":"",
"alcohol":true,
"tobacco":false,
"name":"Simple Item",
"description":"",
"children":[
]
}
]
}
],
"entities":[
{
"description":"Items of each type are represented here.",
"alcohol":false,
"tobacco":false,
"type":"SubMenu",
"scheduleIds":[
1
],
"name":"Test Menu",
"children":[
{
"type":"Item",
"price":6.99,
"qtyIncrements":1,
"qtyMin":1,
"qtyMax":25,
"qtyNameSingular":"",
"qtyNamePlural":"",
"alcohol":true,
"tobacco":false,
"name":"Simple Item",
"description":"",
"children":[
]
}
]
},
{
"type":"Item",
"price":6.99,
"qtyIncrements":1,
"qtyMin":1,
"qtyMax":25,
"qtyNameSingular":"",
"qtyNamePlural":"",
"alcohol":true,
"tobacco":false,
"name":"Simple Item",
"description":"",
"children":[
]
}
],
"warnings":[
{
"entityId":8,
"type":"tobacco"
},
{
"entityId":2,
"type":"alcohol"
}
],
"message":[
]
}
The fetch for the menu resource includes the schedule, menu structure, and an array of all entities. The array of all entities includes entities that have not been added to the menu structure.
GET /merchant/admin/menu?merchantId=1234
POST /merchant/admin/menu/structure
{
"merchantId": 1234,
"menu": [
{
"description": "Items of each type are represented here.",
"alcohol": false,
"tobacco": false,
"type": "SubMenu",
"scheduleIds": [],
"name": "Test Menu",
"children": [
{
"type": "Item",
"price": 6.99,
"qtyIncrements": 1,
"qtyMin": 1,
"qtyMax": 25,
"qtyNameSingular": "",
"qtyNamePlural": "",
"alcohol": true,
"tobacco": false,
"name": "Simple Item",
"description": "",
"children": [
{
"type": "Image",
"url": "https://static.delivery.com/merchant_logo.php?id=1234",
"name": "Simple Item Image",
"children": []
}
]
},
{
"type": "Item",
"price": 0,
"qtyIncrements": 1,
"qtyMin": 1,
"qtyMax": 25,
"qtyNameSingular": "",
"qtyNamePlural": "",
"alcohol": false,
"tobacco": false,
"name": "Item",
"Price Group": "",
"description": "",
"hidden": false,
"children": [
{
"type": "PriceGroup",
"selectionsMin": 1,
"selectionsMax": 1,
"selectionType": "radio",
"name": "Pick One",
"description": "",
"children": [
{
"type": "Option",
"price": 1.99,
"qtyIncrements": 1,
"qtyMax": 1,
"name": "Small",
"description": ""
},
{
"type": "Option",
"price": 2.99,
"name": "Medium",
"description": ""
},
{
"type": "Option",
"price": 3.99,
"name": "Large",
"description": ""
}
]
}
]
},
{
"type": "Item",
"price": 6.99,
"qtyIncrements": 1,
"qtyMin": 1,
"qtyMax": 25,
"qtyNameSingular": "",
"qtyNamePlural": "",
"alcohol": true,
"tobacco": true,
"name": "Item",
"Option Group": "Single",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionsMin": 1,
"selectionsMax": 1,
"name": "Single Option Group",
"description": "",
"hidden": false,
"children": [
{
"type": "Option",
"price": 0,
"name": "Un",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Dos",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Tres",
"description": ""
}
]
}
]
},
{
"type": "Item",
"price": 6.99,
"qtyIncrements": 1,
"qtyMin": 1,
"qtyMax": 25,
"qtyNameSingular": "",
"qtyNamePlural": "",
"name": "Item",
"Option Group": "Quantity",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionsMin": 5,
"selectionsMax": 5,
"selectionsDepends": false,
"selectionType": "quantity",
"name": "Option Group Quantity (Select 5)",
"description": "",
"children": [
{
"type": "Option",
"price": 0,
"name": "Option 1",
"description": "",
"children": []
},
{
"type": "Option",
"price": 0,
"name": "Option 2",
"description": "",
"children": []
},
{
"type": "Option",
"price": 0,
"name": "Option 3",
"description": "",
"children": []
}
]
}
]
},
{
"type": "Item",
"scheduleIds": [
1
],
"price": 6.99,
"qtyIncrements": 1,
"qtyMin": 1,
"qtyMax": 25,
"qtyNameSingular": "",
"qtyNamePlural": "",
"name": "Item",
"Option Group": "Upto One",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionType": "upToOne",
"name": "Optional Condiments",
"description": "",
"children": [
{
"type": "Option",
"price": 1.99,
"qtyIncrements": 1,
"qtyMax": 1,
"name": "Egg Roll",
"description": ""
},
{
"type": "Option",
"price": 2.99,
"name": "Tuna Roll",
"description": ""
},
{
"type": "Option",
"price": 3.99,
"name": "Jellyfish Roll",
"description": ""
}
]
}
]
},
{
"type": "Item",
"price": 6.99,
"qtyIncrements": 1,
"qtyMin": 1,
"qtyMax": 25,
"qtyNameSingular": "",
"qtyNamePlural": "",
"name": "Item",
"Option Group": "Nested Option Group",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionType": "radio",
"name": "Choice of Combo",
"description": "",
"children": [
{
"type": "Option",
"price": 0,
"name": "Burger and Soda",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionType": "radio",
"name": "Choice of Soda",
"description": "",
"children": [
{
"type": "Option",
"price": 0,
"name": "Pepsi",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Coke",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Sprite",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Fanta",
"description": ""
}
]
}
]
},
{
"type": "Option",
"price": 0,
"name": "Pizza and Soda",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionType": "radio",
"name": "Choice of Soda",
"description": "",
"children": [
{
"type": "Option",
"price": 0,
"name": "Pepsi",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Coke",
"description": ""
},
{
"type": "Option",
"price": 0,
"qtyIncrements": 1,
"qtyMax": 1,
"name": "Sprite",
"description": ""
},
{
"type": "Option",
"price": 0,
"qtyIncrements": 1,
"qtyMax": 1,
"name": "Fanta",
"description": ""
}
]
}
]
},
{
"type": "Option",
"price": 0,
"qtyIncrements": 1,
"qtyMax": 1,
"name": "Chowmein and Soda",
"description": "",
"children": [
{
"type": "OptionGroup",
"selectionType": "radio",
"name": "Choice of Soda",
"description": "",
"children": [
{
"type": "Option",
"price": 0,
"qtyIncrements": 1,
"name": "Pepsi",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Coke",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Sprite",
"description": ""
},
{
"type": "Option",
"price": 0,
"name": "Fanta",
"description": ""
}
]
}
]
}
]
}
]
}
]
}
]
}
To submit an entire menu structure, you must still have previously created the menu schedules if necessary. In cases of validation errors, the failed entities and it’s children will be excluded. A message will be returned indicating each failure.
POST /merchant/admin/menu/structure
*Menu Structure Breakdown
Entities describe the different product offerings by merchants on delivery.com. The different entity types are described here.
Typical Hierarchy
Entity Type (example)
- Menu (“Dinner Menu”)
- Menu (“Pizzas”)
- Item (“Square Pizza”)
- Option Group (“Pizza Toppings”)
- Option (“Onions”)
- Option (“Sausage”)
- Option Group (“Crust Type”)
- Option (“Thin”)
- Option (“Regular”)
- Item (“Square Pizza”)
- Menu (“Hot beverages”)
- Item (“Coffee”)
- Price Group (“Size”)
- Option (“Small”)
- Option (“Large”)
- Item (“Coffee”)
- Menu (“Pizzas”)
Standard Properties
These properties are present in all entity types.
Property Name | Value | Description |
---|---|---|
id | String | Id of this entity. |
name | String | Name of this entity. |
description | String | Description of this entity. |
type | String | See the different types below. |
children | Entity[] | The child entities of this entity. For example, an option group would have an array of options as children. |
schedule | Integer[] | If the entity is only valid at certain times, this array will be present and contain the schedule ids. The schedules are listed in the Menu Endpoint. This property is only included when applicable, and only on menus and items. |
Menu Entities
Example
{
"id": "N1",
"name": "Weekday Breakfast Menu",
"description": "Available Monday through Friday, 7am to 4pm.",
"schedule": [
2
],
"type": "menu",
"children": [
... zero to many menus AND zero to many items ...
]
}
Menus are collections of items and menus.
Item Entity
Example
{
"id": "N2668",
"name": "Chicken Salad",
"description": "",
"min_qty": 1,
"max_qty": 25,
"price": 3.95,
"max_price": 3.95,
"increment": 0.25,
"qty_name_singular": "lb.",
"qty_name_plural": "lbs.",
"type": "item",
"children": [
zero to many option groups
AND zero to many price groups
AND zero to many options
AND zero to one images
]
},
Items are the actual products. They are added to the cart.
Properties
Items have the standard properties plus the properties below.
Property Name | Value | Description |
---|---|---|
min_qty | Float | The mininum quantity that you can select of this item. If you have a quantity select, this should be the first option. |
max_qty | Float | The maximum quantity that you can select of this item. If you have a quantity select, this should be the last option. |
price | Float | The base price of this item. |
max_price | Float | How much this item could cost after selecting options. |
increment | Float | How much to increment the quantity select by. This is usually 1, but if you’re buying something like deli meat, it might be 0.25 (for lb.) |
qty_name_singular | String | Sometimes included. Description of the quantity select. For most items, you’re just selecting {increment} {name}, like ’1 Burger’, but sometimes you’re selecting {qty * increment} {qty_name_singular} of {name}, like ’1 lb of Chicken Salad’. |
qty_name_plural | String | Sometimes included. See above, except with the example ’1.5 lbs of Chicken Salad’. |
Option Group Entity
Example
{
"id": "N53",
"name": "Slice Toppings",
"description": "What do you want on your pizza?",
"min_selection": 0,
"max_selection": 13,
"sel_dep": 0,
"type": "option group",
"children": [
zero to many option groups
AND zero to many options
]
}
Some items have options. An option group (“Pizza Toppings”) is a collection of options (“Cheese, Mushrooms”).
Properties
Items have the standard properties plus the properties below.
Property Name | Value | Description |
---|---|---|
min_selection | Integer | The minimum number of children options that must be selected within this option group. |
max_selection | Integer | The maximum number of children options that can be selected within this option group. |
sel_dep | 0/1 | When this equals 1, the ‘min/max_selection’ values should be multiplied by the quantity that the user selects. For example, if a the item is “Dozen Bagels” with a min and max selection of 12 and the user selects a quantity of 2 (dozen bagels), the actual min and max selection would be 24. |
Option Entity
Example
{
"id": "N645",
"name": "Extra Cheese",
"description": "",
"price": 1.5,
"max_price": 0,
"type": "option",
"children": [
... zero to many option groups
AND zero to many options ...
]
},
{
"id": "N646",
"name": "Pepperoni",
"description": "",
"price": 1.5,
"max_price": 0,
"type": "option",
"children": []
},
Some items have options. An option group (“Pizza Toppings”) is a collection of options (“Cheese, Mushrooms”).
Properties
Options have the standard properties plus the properties below.
Property Name | Value | Description |
---|---|---|
price | Float | The base price of this option. |
max_price | Float | The maximum price of this option when considering children entities that have additional charges. |
Price Group Entity
{
"id": "N4",
"name": "Pick One",
"description": "",
"min_selection": "1",
"max_selection": "1",
"type": "price group",
"children": [
{
"id": "N5",
"name": "Small",
"description": "",
"price": "1.99",
"max_price": 0,
"type": "option",
"children": []
},
{
"id": "N6",
"name": "Medium",
"description": "",
"price": "2.99",
"max_price": 0,
"type": "option",
"children": []
},
{
"id": "N7",
"name": "Large",
"description": "",
"price": "3.99",
"max_price": 0,
"type": "option",
"children": []
}
]
}
A price group is just like an option group. The only difference is in how the item is priced.
- For an item with option group(s), the total price = item price plus the sum of all selected children options’ prices.
- For an item with a price group, the total price = the price of the selected option under the price group.
Properties
Price groups have the same properties as option groups.
Image Entity
Example
{
"id": "N56",
"name": "Simple Item IMAGES",
"url": "/images/path/1234.jpg",
"description": null,
"type": "image",
"children": []
}
An image is a link to a picture of its parent entity.
Properties
Image Entities have the standard properties plus the properties below.
Property Name | Type | Description |
---|---|---|
url | String | The relative URL of this image. You can find the actual article by prefixing it with https://www.delivery.com. |
Menu Schedules
A menu schedule is an array of shifts, as described in the merchant schedule, a shift object is as follows:
{
"day" : 1,
"startTime" : "08:30",
"endTime" : "21:00",
}
Property Name | Value | Description |
---|---|---|
id | integer | The id of the shift |
day | integer | Required if weekly shift – The day of the week as such: Sunday = 0, Monday = 1, …, Saturday = 6 |
date | string | Required if holiday shift – The date of the year in YYYY-mm-dd format |
startTime | string | Required – The time the shift begins in HH:mm format |
endTime | string | Required – The time the shift ends in HH:mm format. The endTime must come after startTime. In the case of a shift going past midnight, set the end time to 24:00, then create a new shift for the second day starting at 00:00. |
Schedule object
{
"id" : 1,
"name" : "Lunch Specials",
"hours" : [
{
"day" : 1,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 2,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 3,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 4,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 5,
"startTime" : "11:30",
"endTime" : "14:30"
}
]
}
A schedule object is as follows:
Property Name | Value | Description |
---|---|---|
id | integer | The id of the schedule |
name | string | The name of the schedule |
hours | Shift[] | Required – An array of shift objects |
You can get the menu schedules available either by retrieving the entire menu, which includes schedules, or making a get request specifically for menu schedules:
GET /merchant/admin/menu/schedule?merchantId=1234
The menu schedule endpoint only accepts one schedule per api call. When updating a schedule, individual shifts can not be updated, thus you must re-submit all hours for that schedule. To get existing schedules, you must make a GET call on the menu endpoint, see the menu documentation.
Add Schedule
POST /merchant/admin/menu/schedule
{
"merchantId" : "1234",
"schedule" : {
"name" : "Lunch Specials",
"hours" : [
{
"day" : 1,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 2,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 3,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 4,
"startTime" : "11:30",
"endTime" : "14:30"
},
{
"day" : 5,
"startTime" : "11:30",
"endTime" : "14:30"
}
]
}
}
Updates can be used to update either the hours or the name of the schedule.
Change schedule
PUT /merchant/admin/menu/schedule
{
"merchantId" : "1234",
"schedule" : {
"id" : 1,
"name" : "Daily Lunch Specials"
}
}
Deletion should rarely be necessary, as any changes to menu schedules should be handled via updates. If you require a menu schedule to be deleted, please contact your account manager to discuss the issue.
Merchant Admin API
Merchant General Info
{
"location" : {
"city" : "NEW YORK",
"state" : "NY",
"street" : "239 PARK S AVE",
"unit" : "19th & 20th Street",
"zipCode" : "10003",
},
"confirmPhone" : "5555555555",
"contactName" : "Jane Doe",
"cuisines" : [
"Japanese"
],
"fax" : "5555555555",
"name" : "Delivering Dots",
"phone" : "5555555555",
"timeNeeded" : 30,
"type" : "R",
"groupId" : 1,
"delivery" : true,
"pickup" : true,
"description" : ""
}
response
{
"merchantId" : 1234
}
To create a merchant, a number of values must be set.
A sample creation call:
POST /merchant/admin/info
A successful return will give the new id.
In case of failure, reasons will be delivered in the messages. Reasons will most likely be limited to validation or address verification errors.
Property Name | Value | Description |
---|---|---|
location | Object | The address of the merchant |
location.street | string | Required |
location.city | string | Required without zipCode |
location.state | string | Required without zipCode |
location.zipCode | string | Required without city/state |
location.unit | string | Additional info such as cross street |
name | string | Required – The name of the merchant |
cuisine | array | Array of cuisines the merchant offers – at least 1 is required |
phone | string | Required – Merchant phone number |
fax | string | Fax number for order confirmation -required if using fax confirmation |
confirmPhone | string | Required – Phone number for order confirmation |
description | String | Description generated by the merchant |
type | R/C/F/I/W/U/P/Z | Required – Type of merchant. See Merchant Search. |
timeNeeded | integer | The number of minutes estimated before an order will be delivered |
groupId | integer | Required – The groupId given to you by your account manager |
convenienceFee | float | A percentage value that will be charged on each order separately from the delivery fee (ex: 2.5 adds an extra 2.5% of the order subtotal to the total) |
An update call is made with a PUT call, the only difference being that the only required field is the merchantId. For simplicity, since all calls relevant to a merchant (ex: menu, delivery range, etc) use the ‘merchantId’ key, the id in the merchant info calls will also use ‘merchantId’ as the key rather than ‘id’. For all other data sets, the id key will be ‘id’.
GET merchant info
To get existing information about a merchant, use a GET request:
GET /merchant/admin/info?merchantId=1234
In GET calls, an ‘active’ value is returned indicating whether the merchant is active on our site. The POST and PUT calls do not have direct access to this value. Instead there are activate and deactivate calls. When the activation call is made, a set of sanity checks are ran. If any of the sanity checks fail, a 400 response will be given with messages indicating the reason. If there are no problems, the merchant will be submitted for final review by a member of our staff.
Activate merchant
{
"merchantId": 1234
}
Example activate call:
POST /merchant/admin/activate
Deactivate merchant
{
"merchantId": 1234,
"deactivationId": 220
}
When deactivating, we require a deactivation type to be selected.
Example deactivate call:
POST /merchant/admin/deactivate
Deactivation Id | Description |
---|---|
220 | Temporary Removal |
221 | Permanent Removal |
The above mentioned sanity checks include:
- The menu structure should not be empty
- No menu in the menu structure should be empty
- Items/Options should not have more than one price group
- Items that have a price of 0 should have a price group
- Radio option groups and price groups should have more than one option
- Radio option groups should have at least one option with a price of 0
- Min/max selection for option groups should be valid for the number of children (ex: min selection of 5 is invalid when only 3 options are present)
- The merchant should have at least one cuisine
- The merchant should have an order type available (pickup and/or delivery)
- The merchant should have at least one delivery zone
- Business and delivery hours should be populated
- There should be no time where no menu is available during operation hours (ex: a merchant is open from 10am to 10pm, has a lunch menu of 11am-1pm and a dinner menu of 5pm-8pm, but no standard menu for the rest of the day)
Delivery Zones
There are three types of delivery zones. A merchant may have multiple delivery zones, each with it’s own fee.
Zone Type | Description |
---|---|
Zip Code | A single zip code |
Radius | A specific distance from the merchant’s location |
Polygon | A polygon of lat/long coordinates |
Create delivery zones
{
"merchantId" : "1234",
"deliveryZones" : [
{
"fixedFee" : 2,
"polygon" : [
{
"latitude" : 40.728233,
"longitude" : -73.9841
},
{
"latitude" : 40.735779,
"longitude" : -74.002083
},
{
"latitude" : 40.748981,
"longitude" : -73.992638
},
],
"orderMinimum" : 5,
"type" : "polygon",
},
{
"fixedFee" : 2,
"zipCode" : "10038",
"orderMinimum" : 5,
"type" : "zipCode",
},
{
"percentFee" : 10,
"radius" : 3,
"orderMinimum" : 5,
"type" : "radius",
},
]
}
A sample create call:
POST /merchant/admin/zones
Property Name | Value | Description |
---|---|---|
merchantId | integer | The merchant that the delivery zone is for |
deliveryZones | DeliveryZone[] | An array of DeliveryZone objects |
A delivery zone object:
Property Name | Value | Description |
---|---|---|
id | integer | The id of the delivery zone |
fixedFee | float | Required without percentFee – a flat dollar amount |
percentFee | float | Required without fixedFee – a percent value on the order amount (can not be combined with fixedFee) |
type | radius | polygon |
radius | float | Required if type is radius – distance in miles from the merchant |
zipCode | string | Required if type is zipCode – a zip code the merchant delivers to |
polygon | array | Required if type is polygon – a clockwise array of latitude/longitude coordinates |
PUT merchant zones
{
"merchantId" : 1234,
"deliveryZones" : [
{
"fixedFee" : 5,
"id" : 25357326,
"polygon" : [
{
"latitude" : 40.728233,
"longitude" : -73.9841
},
{
"latitude" : 40.735779,
"longitude" : -74.002083
},
{
"latitude" : 40.748981,
"longitude" : -73.992638
},
],
"orderMinimum" : 5,
"percentFee" : 0,
"type" : "polygon",
}
]
}
In the update PUT call, an id is required for each delivery zone:
PUT /merchant/admin/zones
GET merchant zones
A GET call expects the ‘merchantId’ parameter. A sample return:
GET /merchant/admin/zones?merchantId=1234
Response:
{
"deliveryZones" : [
{
"fixedFee" : 1, //either fixedFee or percentFee will be populated, not both
"id" : 681,
"polygon" : [
{
"latitude" : 40.728233,
"longitude" : -73.9841
},
{
"latitude" : 40.735779,
"longitude" : -74.002083
},
{
"latitude" : 40.748981,
"longitude" : -73.992638
},
],
"orderMinimum" : 5,
"percentFee" : 0,
"type" : "polygon", //indicates the field to look for, either polygon, zipCode, or radius
}
]
}
DELETE merchant zones
To delete delivery zones, include a comma separated list of ids:
DELETE /merchant/admin/zones?merchantId=1234&deliveryZoneIds=1,2,3
If you would prefer to simply delete all delivery zones, you may make a truncate call:
DELETE /merchant/admin/zones/truncate?merchantId=1234
Merchant Integration Overview
The first step in an integration process with Delivery.com is to start creating merchants. The creation of merchants involves a number of endpoints to populate various data sets. These data sets are outlined below.
Getting Started
Before you may use this resource, you will need to contact us to have your api account set up to allow for use of the Client Credentials authentication flow. This resource will typically be called solely by a server rather than having a customer facing front-end, thus the Authorization Code flow is not applicable.
You will also need a merchant group set up, which will be used to determine billing information for all merchants. If you represent multiple businesses, you may need multiple merchant groups so that each business is handled separately. You will be given an id for each merchant group (referred to as “group id”). Each merchant group will be linked to your api account, and can be linked to multiple accounts if necessary, thus only permitted accounts will be allowed to edit and create merchants under each merchant group.
Authentication
Since a server will be making the api calls, you will need to be given access to our Authentication. This will allow your server to make api calls on your behalf using your email and password. You should pass ‘global,merchant’ to the scope parameter.
General Information
This includes basic information about the merchant: location, contact information, name, merchant type, description, etc. This will be the first api call to be made to set up a merchant and will return a merchant id. You should retain the merchant id for use with the other api endpoints and to make future updates. When creating a merchant, you must include a group id, you may have multiple group ids. If you do not have a group id, speak with your account manager.
Schedule
The schedule, as expected, determines the hours of availability of the merchant. We require both business and delivery hours for a merchant, and also allow for the setting of holiday hours.
Delivery Zones
We offer three types of delivery zones: zip code, radius, and polygon. You may use any combination of these types to specify where the merchant delivers to. For pickup orders, if offered, the merchant will be displayed in search results based on distance from the search address.
Menu
We offer a fairly flexible menu structure that should be able to accommodate most merchant menus with minimal manipulation. For the purposes of order integration, each menu element accepts a third party id that will allow you to easily match items in an order to your own records.
Activation
Once all of the above information has been populated, you are ready to activate the merchant. We have a number of sanity checks that will run when an activation call is made. If all pass, the merchant will be put into a queue for review by our staff. For more information on this, see the General Information page.
Updates
Each of these endpoints allows for updating data. The merchant id is required for all calls, as for many of the object the id provided is specific to the merchant. It may be simpler, depending on your use case, to remove all data and re-insert the updated data rather than attempting to match record to record. Updates will not require re-approval, so beware that incorrect data will be reflected immediately on the front-end.
Order Integration
We offer a number of ways to receive and confirm orders: * Fax delivery and voice confirmation * Email delivery and click-to-confirm * Online portal * Api – not yet available
Order Confirmation Methods
We support a variety of methods to confirm orders:
Delivery Method | Response Method | Notes |
---|---|---|
Fax | Voice | An order is sent via fax with a confirmation number, followed by a phone call requesting that confirmation number |
Online | Online | Unconfirmed orders are listed and confirmed via a dashboard |
HTTP Post | Response code | An order in JSON format will be sent via post |
Link | An email is sent with a link to confirm |
Http Post
Sample Order
{
"order": {
"merchant": {
"name": "NYC Pizzeria",
"id": 1234,
"address": {
"street": "123 Broadway",
"unit": "",
"city": "NEW YORK",
"state": "NY",
"zipCode": "10001",
"longitude": -74.005836,
"latitude": 40.710125
}
},
"customer": {
"firstName": "John",
"lastName": "Adams",
"email": "JohnAdams@example.com",
"phone": "5554447894",
"address": {
"street": "199 WATER ST",
"unit": "",
"city": "NEW YORK",
"state": "NY",
"zipCode": "10038",
"longitude": -74.004271030426,
"latitude": 40.706888574096
}
},
"charges": {
"subtotal": 24.95,
"deliveryFee": 0,
"preTax": [
{
"label" : "Convenience Fee",
"amount" : 1.50
}
],
"tax": 2.61,
"postTax": [
{
"label" : "Bag Fee",
"amount" : 0.25
}
],
"tip": 4,
"total": 33.33
},
"cart": [
{
"id": 16,
"thirdPartyId": 26,
"name": "Hawaiian Pizza",
"type": "Item",
"children": [
{
"id": 17,
"thirdPartyId": 65,
"name": "Pick One",
"type": "PriceGroup",
"children": [
{
"id": 18,
"thirdPartyId": 24,
"name": "16 Inch",
"type": "Option",
"children": [
{
"id": 117,
"thirdPartyId": 118,
"name": "16 Inch Pizza Toppings",
"type": "OptionGroup",
"children": [
{
"id": 130,
"thirdPartyId": 125,
"name": "Broccoli",
"type": "Option",
"children": [
],
"quantity": 1,
"price": 0,
"extendedPrice": 0,
"instructions": ""
},
{
"id": 125,
"thirdPartyId": 167,
"name": "Fresh Garlic",
"type": "Option",
"children": [
],
"quantity": 1,
"price": 0,
"extendedPrice": 0,
"instructions": ""
},
{
"id": 136,
"thirdPartyId": 185,
"name": "Jalapenos",
"type": "Option",
"children": [
],
"quantity": 1,
"price": 0,
"extendedPrice": 0,
"instructions": ""
}
],
"quantity": 1,
"price": 0,
"extendedPrice": 0,
"instructions": ""
}
],
"quantity": 1,
"price": 0,
"extendedPrice": 0,
"instructions": ""
}
]
}
],
"quantity": 1,
"price": 0,
"extendedPrice": 0,
"instructions": ""
}
],
"id": 31478948,
"instructions": "Ring the bell",
"timePlaced": "2014-08-19T21:58:41+0000",
"timeRequested": "2014-08-19T21:58:41+0000",
"type": "pickup"
}
}
Sample Response
{
"message" : "There was an internal error."
}
In this method, an endpoint is provided by the third party which will accept an HTTP Post request with the data for an individual order. The receiving endpoint should respond with either a 200, indicating the order is good, or 400, indicating the order is bad.
The provided endpoint should expect a JSON object with these properties:
Property | Type | Notes |
---|---|---|
instructions | String | Instructions given by the user for the merchant |
timePlaced | Time | Format: ISO 8601. The time that the order was submitted to our system |
timeRequested | Time | Format: ISO 8601. The time that the user has requested the order be delivered, if it matches timePlaced, it is for ASAP |
type | String | Either ‘pickup’ or ‘delivery’ |
merchant | Object | |
merchant.name | String | |
merchant.id | Integer | Our internal id for the merchant |
merchant.address | Address | See below for Address format |
customer | Object | |
customer.id | Integer | |
customer.firstName | String | |
customer.lastName | String | |
customer.email | ||
customer.phone | Phone | 10 digit phone number without formatting (ex: 5554443434) |
customer.address | Address | See below for Address format |
charges | Object | A list of charges associated with the order, including the total, tip, and tax |
charges.subtotal | Float | The total amount of the food and drinks |
charges.deliveryFee | Float | The flat or percent fee charged for delivery |
charges.preTax | Array | Array of charges that are applied to the order before tax (these are taxed as well) |
charges.tax | Float | |
charges.postTax | Array | Array of charges that are applied to the order after tax (these are not taxed) |
charges.tip | Float | The amount of gratuity the customer has elected to pay |
charges.total | Float | |
cart | Array | Array of Cart Entities. See below for format |
The charges referenced above in the ‘preTax’ and ‘postTax’ properties are formatted as such:
Property | Type | Notes |
---|---|---|
label | String | The name of the charge |
amount | Float | The value of the charge |
The Address object referenced above is formatted as such:
Property | Type | Notes |
---|---|---|
street | String | |
unit | String | Used for apartment number, floor, or a nearby landmark/cross street |
city | String | |
state | String | Two letter format (ex: NY, NJ, CT) |
zipCode | String | Five digit postal code |
longitude | Float | |
latitude | Float |
The array of Cart Entities is referenced above is a tree, based on the menu structure and selections. A selected Item may have a child OptionGroup or PriceGroup, each of which would have selected Options with their respective prices. Note that an Option could have child OptionGroups. See the Menu Structure documentation.
Property | Type | Notes |
---|---|---|
id | Integer | The unique id of the menu entity |
thirdPartyId | String | Null |
type | String | Item |
quantity | Float | |
price | Float | (Item,Option only) The price of an individual entity, with the added cost of any options selected |
extendedPrice | Float | (Item,Option only) The full price of the line item. (i.e. price * quantity) |
instructions | String | (Item,Option only) Instructions given for the particular item or option (ex: no cheese) |
children | Array | Array of Cart Entities |
If there is an error, the endpoint should return a 400 status code. An optional message may be passed in the ‘message’ namespace in a json response. This message will be attached to the order.
Confirmation Method
Each merchant will need an order confirmation method set. See the supported methods documentation for a description of each method.
Each confirmation method will accept varying parameters depending on its type:
POST /merchant/admin/confirmation
Property Name | Value | Description |
---|---|---|
merchantId | integer | |
confirmationMethod | object | See the respective method for applicable properties |
Currently only HTTP Post is supported by this endpoint.
HTTP Post
{
"merchantId": 1234,
"confirmationMethod": {
"method": "post",
"url": "www.example.com"
}
}
As described in the supported methods documentation, this method will send an http post request for each order to a provided endpoint. Only one endpoint is allowed per merchant, thus a subsequent call will update the url if one is already set.
POST CONFIRMATION METHOD OBJECT:
Property Name | Value | Description |
---|---|---|
method | string | post |
url | url | The endpoint which will accept the order json |
Note: The url should not include the protocol (http/https). It should include any identification parameters necessary, such as an api key.
Confirming / Cancelling Orders
Order Confirmation
HTTP Request
PUT /merchant/admin/orders/integration/confirm?client_id={client_id}
Resource Information
URL Parameter | Value |
---|---|
client_id | Your API Key |
Request Body
{
"estimate_minutes": 45,
"order_id": 22100098
}
Property Name | Value | Description |
---|---|---|
estimate_minutes | integer | An estimate of time needed for the order |
order_id | integer | The id of the order to be confirmed |
Order Cancellation
HTTP Request
PUT /merchant/admin/orders/integration/cancel?client_id={client_id}
Resource Information
URL Parameter | Value |
---|---|
client_id | Your API Key |
Request Body
{
"comments": "Test comment",
"order_id": 18363072
}
Property Name | Value | Description |
---|---|---|
comments | string | Any cancelation notes |
order_id | integer | The id of the order to be canceled |
Merchant Search
View a list of merchants that service a given location. This endpoint does not require authentication, but will return additional information if an access token is included in the Authorization HTTP header.
Request
HTTP Request
GET /merchant/search/{method}
Parameters
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
method | delivery | pickup |
address | String | The address where the user is. Acceptable formats include ‘Address, City, State’ and ‘Address, Zip’. We’ll validate the address for you. See more in the Response section. Note: this is only required if not sending a latitude/longitude. |
latitude | String | The latitude of the search location. Only required if not sending an address. |
longitude | String | The longitude of the search location. Only required if not sending an address. |
Optional Parameters | ||
access_token | String | Include this to see whether a user has favorited each merchant. |
merchant_type | R/C/F/I/W/U/P/Z | Include this to filter search results to a certain merchant type. R - Restaurant. C - Caterer. F - Florist. I - Grocery Store. W - Wine and Liquor Store. U - Drug/Convenience Store. P - Pet Store. Z - Tobacco Shop |
inexact | true | Include this to perform to search approximate addresses, such as finding all merchants who are near a particular zip code, neighborhood, or point of interest. |
Request Body
Do not supply a request body with this method.
Responses
{
"search_address": {
"street": "235 PARK AVE S",
"zip_code": "10003",
"state": "NY",
"city": "NEW YORK",
"latitude": 40.73771,
"longitude": -73.987949
},
"message": [ ],
"promoted_merchants_id": [
"57",
...
],
"merchants": [
{
"id": "57",
"favorite": false,
"summary": {
"name": "Gramercy Bagels",
"cuisines": [
"Sandwiches",
"Bagelry"
],
"phone": "555-555-5555",
"description": "",
"overall_rating": 75,
"num_ratings": 138,
"type": "R",
"type_label": "Restaurant",
"notes": null,
"url": {
"geo_tag": "nyc",
"short_tag": "gramercy-bagels",
"complete": "https://staging.delivery.com/nyc/gramercy-bagels"
},
"activation_date": "2000-11-01"
},
"ordering": {
"delivery_processes_card": true,
"payment_types": [
"credit",
"gift card",
"promotions",
"cash"
],
"is_rds": false,
"time_needed": 30,
"specials": [
{
"name": "10% Off for First Time Users",
"type": "F"
}
],
"last_or_next_order_time": "2014-06-03 22:15:00",
"minimum": 8,
"is_open": true,
"delivery_charge": 0,
"delivery_percent": 0
},
"location": {
"distance": 0.18608809903916,
"street": "246 3rd Ave",
"city": "New York",
"state": "NY",
"zip": "10010",
"longitude": -73.984444,
"latitude": 40.737263,
"landmark": "Between 20th ;amp; 21st."
}
}
...
],
"verticals": [
{
"type": "R",
"count": 389,
"label": "Restaurant"
},
{
"type": "C",
"count": 63,
"label": "Caterer"
}
...
],
"cuisines": [
"Afghan",
"American",
"Argentinian",
"Asian",
"Bagelry",
"Barbeque",
"Brazilian",
"Breakfast",
"Burgers",
"Cafe",
"Caribbean",
"Cheesesteaks",
"Chinese",
"Cuban",
"Deli",
"Desserts",
"Diner",
"Empanadas",
...
],
"popular_cuisines": [
"Sandwiches",
"Italian",
"American",
"Japanese",
"Pizza"
...
]
}
Success
HTTP 200 OK
Property Name | Value | Description |
---|---|---|
search_address | Location | This is the geocoded address that you searched for. You might want to store it for later use in the location API. If passing inexact=true, be sure to check whether is_exact_match is true or false. This will indicate whether the address points to a real location or is just approximate. When dealing with approximate addresses, you’ll need to prompt users for their actual addresses later in the process to add items to their carts. |
merchants | Merchant[] | Array of merchants that service that location |
cuisines | String[] | Array of cuisines that are available to this location |
verticals | vertical[] | Array of json objects containing information about verticals available to that location. See example response above. |
No Results Found
{
"search_address": {
"street": "7452 STONEBROOK DR",
"zip_code": "48187",
"state": "MI",
"city": "CANTON",
"latitude": 42.338348,
"longitude": -83.51164
},
"message": [
{
"code": "no_delivery_results",
"user_msg": "Sorry, no results were found",
"dev_msg": "Sorry, no results were found"
}
],
"promoted_merchants_id": [],
"merchants": [],
"cuisines": []
}
HTTP 200 OK
Ambiguous Location
{
"message": [
{
"code": "loc_multiple_possible",
"user_msg": "Multiple addresses possible.",
"dev_msg": "Multiple addresses possible."
}
],
"addresses": [
{
"street": "1 N Rosedale St",
"city": "Baltimore",
"state": "MD",
"zip": "21229",
"latitude": 39.28602,
"longitude": -76.6689,
"exactMatch": true
},
{
"street": "1 S Rosedale St",
"city": "Baltimore",
"state": "MD",
"zip": "21229",
"latitude": 39.2858,
"longitude": -76.66889,
"exactMatch": true
}
]
}
HTTP 400 Bad Request
Property Name | Value | Description |
---|---|---|
addresses | Location | Possible addresses that the user could have meant. You should show these to the user and have him select the one that he meant. |
Invalid Address
{
"message": [
{
"code": "invalid_address",
"user_msg": "We could not find the address that you submitted. Please double check all the fields and try again.",
"dev_msg": "This address could not be validated."
}
]
}
HTTP 400 Bad Request
Support / FAQ
If you’re stumped, you can find help in the following places: * Delivery.com Partner Support: Please message your Delivery.com contact with any issues you may have. * Customer Service: If there are problems with orders that are impacting end-users (on production server), our customer service team can help with orders or payment issues. They will not be able to help with technical questions about the API.
FAQ – Frequently Asked Questions
Why am I getting an HTTP 401 / INCORRECT API KEY / “ACCT_INVALID_XAUTH” RESPONSE?
All API requests are authenticated and tracked by our system. You will need to either pass in your client_id (for unauthenticated resources) or an oauth access token (for POST requests and customer resources).
Please check out the authentication overview and Access Token overview.
How do I sign up for an accountT?
You will receive an API key upon signing up.
Environment | Sign Up Page |
---|---|
Sandbox | Please contact your Delivery.com representitive |
Production API | Production API Sign Up |
Do you have a list of sample (GEO) Search Addresses that contain plenty of merchants?
- 199 Water Street, 10038
- 1001 6th Avenue, 10018
What Geolocation address formats do you support?
Any fully qualified address queries should work (street address, city, zipcode and state). However, you could also pass in:
Elements | Example |
---|---|
Fully Qualified Address | 1001 6th Avenue, New York, NY 10018 |
Street Address + Zipcode | 1001 6th Avenue, 10018 |
Latitude + Longitude | 40.751992, -73.986582 |
What is the complete list of supported credit card types?
Our API will return one of the following 5 credit ctypes in the “card.type” field of the customer payment endpoint:
- Visa
- MasterCard
- Discover
- American Express
- Diners Club
Is there a way to redeem delivery point rewards via the API?
Sorry to say but we don’t currently support a redirect from our rewards page. Please contact your Delivery.com representative for possible options.
Last Mile Provider API
Scope and Summary
This API specification defines how delivery.com will place delivery requests to authorized Last Mile Providers. For all cases the delivery requests are made for ASAP service (i.e pickup expected under 45 minutes) in the United States.
To become an authorized last mile provider, send us an inquiry at lmp-api@delivery.com.
Currently our API supports the following calls and responses. Each endpoint will be a URL provided to us by you, the last mile provider. When you become an authorized last mile provider, we’ll ask for these URLs :
Endpoint | Description |
---|---|
delivery estimate | a POST call made by delivery.com to the Last Mile Provider with detailed delivery parameters. Last mile provider is expected to respond with estimated price and pickup time estimates. |
book delivery | a POST call made by delivery.com to the Last Mile Provider to book a delivery. This call comes after the “get delivery estimate” call. |
get delivery status | a GET call made by delivery.com to the Last Mile Provider get the delivery status details. |
cancel delivery | a POST call made by delivery.com to Last Mile Provider to cancel a previously booked delivery. |
NB: All endpoints can return a 401 unauthorized as well as a 500 fatal. And lastly, all requests below are from delivery.com to you. To signify everything was processed correctly on your end, return a 200. To signify an error, return anything other than 200.
Delivery Estimate
Request
Sample
{
"pickup": {
"address": "2 clinton st",
"apt": null,
"city": "nyc",
"state": "ny",
"zip": 10002,
"latitude" : 40.706868,
"longitude" : -74.004365
},
"delivery": {
"address": "310 e 3nd st",
"apt": "3d",
"city": "nyc",
"state": "ny",
"zip": 10009,
"latitude" : 40.720345,
"longitude" : -73.978848
},
"gratuity" : 3.50
}
Parameters
Parameters | Values | Description |
---|---|---|
pickup | Object | pickup location |
pickup.address | String | address for pickup(#, street) |
pickup.apt | String | (optional) apartment, suite, unit or floor # |
pickup.city | String | city |
pickup.state | String | state abbreviation such (i.e. NY/CA/DC…) |
pickup.zip | String | zip code |
pickup.latitude | Float | latitude |
pickup.longitude | Float | longitude |
delivery | Object | delivery location |
delivery.address | String | address for delivery(#, street) |
delivery.apt | String | (optional) apartment, suite, unit or floor # |
delivery.city | String | city |
delivery.state | String | state abbreviation such (i.e. NY/CA/DC…) |
delivery.zip | String | zip code |
delivery.latitude | Float | latitude |
delivery.longitude | Float | longitude |
gratuity | Float | 3.50 |
Response
Sample
{
"estimate_id": "123AF019",
"estimated_at": 1437401048,
"estimate_valid_until": 1437402300,
"pickup_eta": 1437401959,
"delivery_eta": 1437403560,
"price": 6.5
}
Parameters
Parameter | Type | Description |
---|---|---|
estimate_id | String | estimate unique id for the Last Mile Provider |
estimated_at | Integer | time delivery estimate is provided – Unix Timestamp |
estimate_valid_until | Integer | time delivery estimate valid until – Unix Timestamp |
pickup_eta | Integer | estimated time to pickup – Unix Timestamp |
delivery_eta | Integer | estimated time to delivery – Unix Timestamp |
price | Float | estimated price of the delivery – in USD |
Errors
HTTP 400 Bad Request
{
"code": 400,
"user_msg": "null is not a valid last mile provider name",
"dev_msg": "null is not a valid last mile provider name"
}
HTTP 401 Unauthorized
HTTP 500 Fatal Error
Book Delivery
Request
Sample
{
"estimate_id": "123AF019",
"order_id": 1233434,
"items": [
{
"name": "Chicken Sandwich",
"quantity": 1
},
{
"name": "Coke",
"quantity": 1
}
],
"pickup": {
"location": {
"address": "2 clinton st",
"apt": null,
"city": "new york",
"state": "ny",
"zip": 10002,
"latitude" : 40.720345,
"longitude": -73.978848
},
"contact": {
"merchant_name": "Merchant XYZ",
"email": "merchantxyz@delivery.com",
"phone": 5553450123
},
"instructions": "NA"
},
"delivery": {
"location": {
"address": "310 east 2nd st",
"apt": "6",
"city": "new york",
"state": "ny",
"zip": 10009,
"latitude" : 40.706868,
"longitude": -74.004365
},
"contact": {
"first_name": "john",
"last_name": "smith",
"company_name": null,
"email": "jsmith@delivery.com",
"phone": 5554450123
},
"instructions": "please wait after ringing, I need to come down to open the building door"
}
}
delivery.com will book a previously estimated delivery from the Last Mile Provider by making a POST request to whatever URL you provide us when signing up.
Parameters
Parameters | Values | Description |
---|---|---|
estimate_id | String | estimate unique id for the Last Mile Provider |
order_id | String | delivery.com unique order id |
items | Object | list of items for the delivery order |
items.name | String | item name |
items.quantity | Integer | item quantity |
pickup | Object | pickup information |
pickup.location | Object | pickup location |
pickup.location.address | String | address for pickup(#,street) |
pickup.location.apt | String | (optional) apartment, suite, unit or floor # |
pickup.location.city | String | city |
pickup.location.state | String | state abbreviation such (i.e. NY/CA/DC…) |
pickup.location.zip | String | zip code |
pickup.location.latitude | Float | latitude |
pickup.location.longitude | Float | longitude |
pickup.contact | Object | pickup contact for order |
pickup.contact.merchant_name | String | merchant name |
pickup.contact.email | String | merchant email |
pickup.contact.phone | String | merchant phone |
pickup.instructions | String | instructions for pickup |
delivery | Object | delivery information |
delivery.location | Object | delivery location |
delivery.location.address | String | address for pickup(#,street) |
delivery.location.apt | String | (optional) apartment, suite, unit or floor # |
delivery.location.city | String | city |
delivery.location.state | String | state abbreviation such (i.e. NY/CA/DC…) |
delivery.location.zip | String | zip code |
delivery.location.latitude | Float | latitude |
delivery.location.longitude | Float | longitude |
delivery.contact | Object | delivery contact for order |
delivery.contact.first_name | String | customer first name |
delivery.contact.last_name | String | customer last name |
delivery.contact.company_name | String | (optional) company name |
delivery.contact.email | String | customer email |
delivery.contact.phone | String | customer phone |
delivery.instructions | String | instructions for delivery |
Response
Parameters
Sample
{
"delivery_id":1234234,
"booked_at":2342342354234532,
"estimate_id": "123AF019",
"order_id": 1233434,
"status":"booked",
"items": [
{
"name": "Chicken Sandwich",
"quantity": 1
},
{
"name": "Coke",
"quantity": 1
}
],
"pickup": {
"location": {
"address": "2 clinton st",
"apt": null,
"city": "new york",
"state": "ny",
"zip": 10002,
"latitude" : 40.706868,
"longitude" : -74.00436
},
"contact": {
"merchant_name": "Merchant XYZ",
"email": "merchantxyz@delivery.com",
"phone": 5553450123
},
"instructions": "NA",
"eta":2342343
},
"delivery": {
"location": {
"address": "310 east 2nd st",
"apt": "6",
"city": "new york",
"state": "ny",
"zip": 10009,
"latitude" : 40.720345,
"longitude" : -73.978848
},
"contact": {
"first_name": "john",
"last_name": "smith",
"company_name": null,
"email": "jsmith@delivery.com",
"phone": 5554450123
},
"instructions": "please wait after ringing, I need to come down to open the building door",
"eta" : 234235345
}
}
Parameters | Values | Description |
---|---|---|
delivery_id | String | delivery unique id for the Last Mile Provider |
estimate_id | String | estimate unique id for the Last Mile Provider |
order_id | String | delivery.com unique order id |
booked_at | Integer | time delivery is created – Unix Timestamp |
price | Float | estimated price of the delivery – in USD |
status | Enum | See Delivery Status descriptions below |
items | Object | list of items for the delivery order |
items.name | String | item name |
items.quantity | Integer | item quantity |
pickup | Object | pickup information |
pickup.location | Object | pickup location |
pickup.location.address | String | address for pickup(#,street) |
pickup.location.apt | String | (optional) apartment, suite, unit or floor # |
pickup.location.city | String | city |
pickup.location.state | String | state abbreviation such (i.e. NY/CA/DC…) |
pickup.location.zip | String | zip code |
pickup.location.latitude | Float | latitude |
pickup.location.longitude | Float | longitude |
pickup.contact | Object | pickup contact for order |
pickup.contact.merchant_name | String | merchant name |
pickup.contact.email | String | merchant email |
pickup.contact.phone | String | merchant phone |
pickup.instructions | String | instructions for pickup |
pickup.eta | Integer | estimated time to pickup – Unix Timestamp |
delivery | Object | delivery information |
delivery.location | Object | delivery location |
delivery.location.address | String | address for pickup(#,street) |
delivery.location.apt | String | (optional) apartment, suite, unit or floor # |
delivery.location.city | String | city |
delivery.location.state | String | state abbreviation such (i.e. NY/CA/DC…) |
delivery.location.zip | String | zip code |
delivery.location.latitude | Float | latitude |
delivery.location.longitude | Float | longitude |
delivery.contact | Object | delivery contact for order |
delivery.contact.first_name | String | customer first name |
delivery.contact.last_name | String | customer last name |
delivery.contact.company_name | String | (optional) company name |
delivery.contact.email | String | customer email |
delivery.contact.phone | String | customer phone |
delivery.instructions | String | instructions for delivery |
delivery.eta | Integer | estimated time to delivery – Unix Timestamp |
ERRORS
{
"code": 400,
"user_msg": "null is not a valid last mile provider name",
"dev_msg":
}
HTTP 400 Bad Request
HTTP 401 Unauthorized
HTTP 500 Fatal Error
Delivery Status
Request
delivery.com will request a status update from the Last Mile Provider for an ongoing delivery by making a GET request to whatever URL you provide us when signing up, except with one caveat : we’ll append ‘/{delivery_id}’ to the URL. So if the URL provided was ‘http://example.com/status’ then we’ll make a GET request to ‘http://example.com/status/12334′ for a delivery_id of ’12334′.
Parameters
Parameters | Values | Description |
---|---|---|
delivery_id | String | delivery unique id from the Last Mile Provider |
Sample
GET http://example.com/status/12334
Response
Parameters
Sample
{
"delivery_id":1234234,
"booked_at":2342342354234532,
"estimate_id":"123AF019",
"status_time":2342342354234532,
"price":5.50,
"order_id":1233434,
"status":"to_pickup",
"courier":{
"first_name":"John",
"last_name":"Smith",
"phone":5553232323,
"location":{
"latitude":72.2343234,
"longitude":-12.3234
}
},
"items":[
{
"name":"Chicken Sandwich",
"quantity":1
},
{
"name":"Coke",
"quantity":1
}
],
"pickup":{
"location":{
"address":"2 clinton st",
"apt":null,
"city":"new york",
"state":"ny",
"zip":10002,
"latitude":40.706868,
"longitude":-74.004365
},
"contact":{
"merchant_name":"Merchant XYZ",
"email":"merchantxyz@delivery.com",
"phone":5553450123
},
"instructions":"NA",
"eta":2342343
},
"delivery":{
"location":{
"address":"310 east 2nd st",
"apt":6,
"city":"new york",
"state":"ny",
"zip":10009,
"latitude":40.720345,
"longitude":-73.978848
},
"contact":{
"first_name":"john",
"last_name":"smith",
"company_name":null,
"email":"jsmith@delivery.com",
"phone":5554450123
},
"instructions":"please wait after ringing, I need to come down to open the building door",
"eta":234235345
}
}
Parameters | Values | Description |
---|---|---|
delivery_id | String | delivery unique id for the Last Mile Provider |
estimate_id | String | estimate unique id for the Last Mile Provider |
order_id | String | delivery.com unique order id |
booked_at | Integer | time delivery is created – Unix Timestamp |
status_time | Integer | time of status update provided – Unix Timestamp |
price | Float | estimated price of the delivery – in USD |
status | Enum | See Delivery Status descriptions below |
courier | Object | details about courier in charge of the delivery |
courier.first_name | String | courier first name |
courier.last_name | String | courier last name |
courier.phone | String | courier phone number |
courier.location | Object | location of the courier |
courier.location.latitude | Float | courier’s latitude |
courier.location.longitude | Float | courier’s longitude |
items | Object | list of items for the delivery order |
items.name | String | item name |
items.quantity | Integer | item quantity |
pickup | Object | pickup information |
pickup.location | Object | pickup location |
pickup.location.address | String | address for pickup(#,street) |
pickup.location.apt | String | (optional) apartment, suite, unit or floor # |
pickup.location.city | String | city |
pickup.location.state | String | state abbreviation such (i.e. NY/CA/DC…) |
pickup.location.zip | String | zip code |
pickup.location.latitude | Float | latitude |
pickup.location.longitude | Float | longitude |
pickup.contact | Object | pickup contact for order |
pickup.contact.merchant_name | String | merchant name |
pickup.contact.email | String | merchant email |
pickup.contact.phone | String | merchant phone |
pickup.instructions | String | instructions for pickup |
pickup.eta | Integer | estimated time to pickup – Unix Timestamp |
delivery | Object | delivery information |
delivery.location | Object | delivery location |
delivery.location.address | String | address for pickup(#,street) |
delivery.location.apt | String | (optional) apartment, suite, unit or floor # |
delivery.location.city | String | city |
delivery.location.state | String | state abbreviation such (i.e. NY/CA/DC…) |
delivery.location.zip | String | zip code |
delivery.location.latitude | Float | latitude |
delivery.location.longitude | Float | longitude |
delivery.contact | Object | delivery contact for order |
delivery.contact.first_name | String | customer first name |
delivery.contact.last_name | String | customer last name |
delivery.contact.company_name | String | (optional) company name |
delivery.contact.email | String | customer email |
delivery.contact.phone | String | customer phone |
delivery.instructions | String | instructions for delivery |
delivery.eta | Integer | estimated time to delivery – Unix Timestamp |
ERRORS
{
"code":400,
"user_msg":"null is not a valid last mile provider name",
"dev_msg": "null is not a valid last mile provider name"
}
HTTP 400 Bad Request
HTTP 401 Unauthorized
HTTP 500 Fatal Error
Cancel Delivery
Request
delivery.com will cancel an ongoing delivery by the Last Mile Provider by making a POST request to whatever URL you provide us when signing up, except with one caveat : we’ll append ‘/{delivery_id}’ to the URL. So if the URL provided was ‘http://example.com/cancel’ then we’ll make a POST request to ‘http://example.com/cancel/12334′ for a delivery_id of ’12334′.
Parameters
Parameters | Values | Description |
---|---|---|
delivery_id | String | delivery unique id from the Last Mile Provider |
SAMPLE
POST http://example.com/cancel/12334
Response
HTTP 200 OK
ERRORS
{
"code":400,
"user_msg":"null is not a valid last mile provider name",
"dev_msg": "null is not a valid last mile provider name"
}
HTTP 400 Bad Request
HTTP 401 Unauthorized
HTTP 500 Fatal Error
Delivery Status Descriptions
More details on the different values supported for delivery status
Status | Description |
---|---|
booked | delivery is successfully created and courier en-route soon |
denied | delivery request denied (no-driver, available, estimate no more valid…) |
to_pickup | courier actively on his way to pickup location |
at_pickup | courier at pickup location |
to_delivery | courier picked up the order and actively on his way to delivery location |
at_delivery | courier at delivery location |
delivered | delivery completed |
cancelled | delivery cancelled |
failed | the delivery was not complete because of a merchant or customer facing issue (like merchant is closed or customer is not home) |
Testing
After you email lmp-api@delivery.com with the 4 URLs above, we’ll provide you with 4 test endpoints that you can curl in order to instigate a call to your system. For example, you’ll curl a test delivery estimate endpoint we’ll provide you, which will cause delivery.com to POST to your delivery estimate URL.
Delivery Points
Overview Customers can use delivery points to redeem prizes, the prizes could be a gift card, a gift item or a charity donation.
Get Prizes
Response
{
"message": [],
"prizes": {
"charity_prizes": [
{
"name": "Fisher Center For Alzheimer's Research Foundation Donation",
"charity_id": 2,
"description": "Give back by converting your Delivery Points into a cash donation to the Fisher Center For Alzheimer's Research Foundation. When you redeem your Delivery Points, Delivery.com will convert them into cash and send your donation to the Fisher Center For Alzheimer's Research Foundation. Upon receipt of your donation, a Fisher Center For Alzheimer's Research Foundation acknowledgement letter will be sent to you. Please consult your own tax advisor as to the substantiation requirements for claiming charitable contributions on your income tax return. \nThe Fisher Center For Alzheimer's Research Foundation is a leading source of funding for Alzheimer's research. The Fisher Center for Alzheimer's Research Foundation serves Alzheimer's patients and their families by seeking to understand the causes of, discover a cure for, and improve the lives of people with Alzheimer's disease. Nobel laureate Dr. Paul Greengard directs the Foundation's team of internationally renowned scientists, who have been at the forefront of research to understand and find a cure for Alzheimer's disease. They have a four star rating from Charity Navigator and only 8% of their funds are used for overhead expenses.\n<b>By converting your Delivery Points into a cash donation to Fisher Center For Alzheimer's Research Foundation, you authorize Delivery.com to transmit your name and the dollar amount of your donation to Fisher Center For Alzheimer's Research Foundation.</b> Delivery.com is not affiliated with Fisher Center For Alzheimer's Research Foundation and does not guarantee or assume any, and shall have no, responsibility or liability for Fisher Center For Alzheimer's Research Foundation's use of your information.",
"image_name": "https://staging.delivery.com/images/partners/charity/fishercenter_logo.png",
"prize_options": [
{
"prize_id": 128,
"charity_amount": 5,
"points_needed": 10000,
"require_address": true
},
{
"prize_id": 129,
"charity_amount": 15,
"points_needed": 30000,
"require_address": true
},
{
"prize_id": 130,
"charity_amount": 25,
"points_needed": 45000,
"require_address": true
}
]
}
],
"gift_prizes": [
{
"prize_id": 49,
"name": "$5 delivery.com Gift Card",
"description": "Treat yourself to $5 off your next order with a delivery.com gift card. \ndelivery.com gift cards will be added directly to your account.",
"image_name": "https://staging.delivery.com/images/prizes/GiftCard_5.jpg",
"points_needed": 12500,
"require_address": false
},
{
"prize_id": 60,
"name": "$50 delivery.com Gift Card",
"description": "Invite your friends over for dinner. With a $50 delivery.com gift card, you can order for the whole group. \ndelivery.com gift cards will be added directly to your account.",
"image_name": "https://staging.delivery.com/images/prizes/GiftCard_50.jpg",
"points_needed": 85000,
"require_address": false
},
{
"prize_id": 77,
"name": "$20 delivery.com Gift Card",
"description": "Treat a friend - or yourself - to an order from the best spot in the neighborhood with a $20 delivery.com gift card. \ndelivery.com gift cards will be added directly to your account. ",
"image_name": "https://staging.delivery.com/images/prizes/GiftCard_20.jpg",
"points_needed": 40000,
"require_address": false
}
]
}
}
Request
GET /api/marketing/prizes
Parameters None
Redeem Prize
Request
POST /api/marketing/redeem/{prize_id}
Parameters When redeeming a prize which doesn't require an address, please refer to parameters in Table one. When redeeming a prize which requires an address, please refer to parameters in Table two. The address parameters will be validated and used as the shipping address for the prize. To decide whether a prize requires an address or not, please refer to "require_address" value of a prize in Get Prizes endpoint.
Table One
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
prize_id | Integer | The id of the prize from the Get Prizes end point. |
Optional Parameters | ||
comments | string | The comments will be saved in record as well as displaying in the confirmation email to the customer. |
Table Two
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
prize_id | Integer | The id of the prize from the Get Prizes end point. |
street | string | Must be >= 5 characters. |
city | string | Must be >= 2 characters. |
state | string | Must be exactly 2 characters. |
zip | string | Must be exactly 5 characters. |
Optional Parameters | ||
unit | string | Apartment number or suite number or company name. |
Request Body When address is NOT required to redeem the prize.
{
"comments" : "redeem $5 gift card",
}
When address is required to redeem the prize.
{
"street" : "1718 E 2nd street",
"unit" : "single",
"city" : "Brooklyn",
"state" : "NY",
"zip" : "11223",
}
Response
When address is NOT required to redeem the prize.
{
"message": [
{
"code": "prize_redeemed",
"user_msg": "Thanks! Your reward has been redeemed successfully.",
"dev_msg": "Thanks! Your reward has been redeemed successfully."
}
],
"info": {
"prize": {
"points_redeemed": 12500,
"item_name": "$5 delivery.com Gift Card",
"gift_code": "KMN5NE3NFX56JP49",
"points_remaining": 77000
}
}
}
When address is required to redeem the prize.
{
"message": [
{
"code": "prize_redeemed",
"user_msg": "Thanks! Your reward has been redeemed successfully.",
"dev_msg": "Thanks! Your reward has been redeemed successfully."
}
],
"info": {
"address": {
"street": "1718 E 2ND ST",
"city": "BROOKLYN",
"state": "NY",
"zip": "11223",
"unit": "SINGLE"
},
"prize": {
"points_redeemed": 10000,
"item_name": "Fisher Center for Alzheimer's Research Foundation Donation $5",
"points_remaining": 89500
}
}
}
Example Program
package com.brinkmat.api;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;<script></script>
public class DcomRestExample
{
final static String host = "http://sandbox.delivery.com/";
final static String GUEST_TOKEN = "Guest-Token";
final static String AUTH_TOKEN = "Authorization";
final static String GUEST_TOKEN_URL = "customer/auth/guest";
final static String CUSTOMER_CART_URL = "customer/cart";
final static String CHECKOUT_URL = "customer/cart";
final static String CC_URL = "customer/cc";
final static String AUTH_URL = "customer/auth";
final static String LOCATION_URL = "customer/location";
final static String ORDER_URL = "customer/orders/recent";
final static String SEARCH_URL = "merchant/search/delivery";
final static String SEARCH_ADDRESS = "1330 1st Ave, 10021";
final static String ADDRESS_APT = "Apt 123";
final static String CLIENT_ID = "NDU1MWU1YjM4NzczMjljN2ZlNjFkODFkNDhlMjdkZGZk";
final static String ORDER_TYPE = "delivery";
public static void main(String[] args) throws IOException
{
// 1) Go to https://staging.delivery.com , scroll to bottom, click
// 'developers', click 'become api user'
// 2) Enter info
// 3) Remember your Client Id and Secret, and fill them in below
// 4) click on 'add one' to add a URL redirect, enter 'http://localhost'
// or whatever you want, click Add URI, and fill that URI in redirectURI
// below
String clientSecret = "OGpYvTZubYUUlqo2zkgwDbmr7sXGOK1UMCDXqFTE";
String redirectURI = "http://localhost";
String urlToAddCCInBrowser = "http://sandbox.delivery.com/third_party/credit_card/add?client_id=" + CLIENT_ID + "&redirect_uri=" + redirectURI
+ "&response_type=code&scope=global";
// I can get a guest-token which allows me to create a cart before the user logs in.
String guestToken = getGuestToken(CLIENT_ID);
// search for a merchant at location from above
JSONObject searchResults = search(SEARCH_ADDRESS);
JSONObject geoCodedLocation = searchResults.getJSONObject("search_address");
System.out.println("My address was geocoded to: " + geoCodedLocation);
int merchantId = getWasabiLobbyId(searchResults);
System.out.println("Successfully found merchant w/ id " + merchantId);
// now that we have the merchant, let's get the menu
String inventory = menu(merchantId);
System.out.println("Inventory for " + merchantId + " is " + inventory);
// now let's add stuff to our cart
addSushi(guestToken, inventory, merchantId);
System.out.println("Added some sushi to my cart. Yum...");
// view the cart
String cart = viewCart(guestToken, null, merchantId, geoCodedLocation);
System.out.println("Cart with guest token : " + cart);
String urlToAuthorizeInBrowser = "http://sandbox.delivery.com/third_party/authorize?client_id=" + CLIENT_ID + "&redirect_uri=" + redirectURI
+ "&response_type=code&scope=global&guest_token=" + guestToken;
System.out.println("Please go to " + urlToAuthorizeInBrowser + " in your browser, sign in or create an account, and you'll be redirected "
+ "to a url that looks like http://localhost/?code=DH8uAFjSO5dq2Alzr37PZPyUZjsGEAgG6MhUcIS9&state=."
+ " Please copy the code portion of in the URL (DH8uAFjSO5dq2Alzr37PZPyUZjsGEAgG6MhUcIS9 in this "
+ "example) and paste it here. I'm waiting for that input :");
String code = new BufferedReader(new InputStreamReader(System.in)).readLine();
// Get an access token as a bridge between
// unauthorizedSessionSpecificToken and an authorized user
String accessToken = getAccessToken(code, CLIENT_ID, clientSecret, redirectURI);
// view the cart
cart = viewCart(null, accessToken, merchantId, geoCodedLocation);
System.out.println("Cart with access token: " + cart);
// get a location id which will be used throughout the api - this should
// be the delivery address
int locationId = createLocation(accessToken, geoCodedLocation, true, null);
System.out.println("Successfully created a location with id " + locationId);
// get the saved CCs for this user
System.out.println("Do you want to add a credit card to this account? Y or N");
if (new BufferedReader(new InputStreamReader(System.in)).readLine().equalsIgnoreCase("y"))
{
System.out.println("Enter the CC info at " + urlToAddCCInBrowser + " . When done, enter 'done' to continue");
while (!new BufferedReader(new InputStreamReader(System.in)).readLine().equalsIgnoreCase("done"))
{
System.out.println("Waiting for you to enter 'done' and hit enter");
}
}
System.out.println("Attempting to place order");
int ccId = Integer.parseInt(viewCCs(accessToken));
Float tip = 2.5f;
String orderNotes = "Please be nice to the doorman. He works so hard.";
String order = checkout(accessToken, tip, orderNotes, ccId, locationId, merchantId);
System.out.println("Just placed an order: " + order);
// now let's get it back again
int orderId = JSONObject.fromObject(order).getInt("order_id");
String orderFromGet = getOrder(accessToken, orderId);
System.out.println("Just got an order: " + orderFromGet);
}
private static String getAccessToken(String code, String clientId, String clientSecret, String redirectURI)
{
String url = "http://sandbox.delivery.com/api/third_party/access_token";
WebResource resource = Client.create().
resource(
UriBuilder.fromUri(url).clone().build().toASCIIString()
);
JSONObject postData = new JSONObject();
postData.put("client_id", clientId);
postData.put("client_secret", clientSecret);
postData.put("redirect_uri", redirectURI);
postData.put("grant_type", "authorization_code");
postData.put("code", code);
ClientResponse resi = resource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(ClientResponse.class, postData.toString());
if (resi.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
return JSONObject.fromObject(resi.getEntity(String.class)).getString("access_token");
} else
{
String rs = resi.getEntity(String.class);
throw new RuntimeException(JSONObject.fromObject(rs).getString("error_description"));
}
}
/**
* This gives you a unique unauthorized code you'll use throughout the api
*
* @param clientId
* when you sign up for an API key, you'll get a client Id
* @return
*/
private static String getGuestToken(String clientId)
{
WebResource resource = Client.create().resource(UriBuilder.fromUri(host + GUEST_TOKEN_URL).queryParam("client_id", clientId).clone().build().toASCIIString());
ClientResponse res = resource.type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
String token = res.getEntity(String.class);
return JSONObject.fromObject(token).getString("Guest-Token");
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static int createLocation(String authToken, JSONObject location, boolean isDoormanBuilding, String aptNum)
{
WebResource resource = Client.create().resource(UriBuilder.fromUri(host + LOCATION_URL).clone().build().toASCIIString());
JSONObject formData = new JSONObject();
formData.put("street", location.get("street"));
formData.put("unit_number", aptNum);
formData.put("city", location.get("city"));
formData.put("state", location.get("state"));
formData.put("zip_code", location.get("zip_code"));
formData.put("phone", "555-555-5555");
ClientResponse res = resource
.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON)
.header(AUTH_TOKEN, authToken)
.post(ClientResponse.class, formData.toString());
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
String locationObj = res.getEntity(String.class);
return Integer.parseInt(JSONObject.fromObject(locationObj).getJSONObject("location").getString("location_id"));
} else
{
String err = res.getEntity(String.class);
throw new RuntimeException(JSONObject.fromObject(err).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static JSONObject search(String address)
{
String url = host + SEARCH_URL;
WebResource resource = Client.create().resource(UriBuilder.fromUri(url).queryParam("address", address).queryParam("client_id", CLIENT_ID).clone().build().toASCIIString());
ClientResponse res = resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).get(ClientResponse.class);
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
String merchantInfoArray = res.getEntity(String.class);
JSONObject searchResult = JSONObject.fromObject(merchantInfoArray);
return searchResult;
} else
{
String msg = JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code");
throw new RuntimeException(msg);
}
}
private static int getWasabiLobbyId(JSONObject searchResult)
{
JSONArray merchantArray = searchResult.getJSONArray("merchants");
if (!merchantArray.isEmpty())
{
for (int i = 0; i < merchantArray.size(); i++)
{
String seoName = merchantArray.getJSONObject(i).getJSONObject("summary").getJSONObject("url").getString("short_tag");
if (seoName.toLowerCase().contains("wasabi-lobby"))
{
return merchantArray.getJSONObject(i).getInt("id");
}
}
}
throw new RuntimeException("Can't find wasabi-lobby");
}
private static String menu(int merchantId)
{
String url = host + "merchant/" + merchantId + "/menu";
WebResource resource = Client.create()
.resource(UriBuilder.fromUri(url).clone().build().toASCIIString());
ClientResponse res = resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).get(ClientResponse.class);
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
String inventory = res.getEntity(String.class);
return inventory;
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static void addSushi(String authToken, String inventoryStr, Integer merchantId)
{
JSONObject inventory = JSONObject.fromObject(inventoryStr);
// We need all this info
String itemId = null;
Integer quantity = null;
String itemNotes = "Extra fishies please";// optional
Map<String,Integer> optionQuantities = new HashMap<String,Integer>();
JSONArray menus = inventory.getJSONArray("menu");
for (int i = 0; i < menus.size(); i++)
{
//I'm using the "Full Menu" because it doesn't have a schedule. It's available all day.
if (menus.getJSONObject(i).getString("name").equals("Full Menu"))
{
JSONArray fullMenuSections = menus.getJSONObject(i).getJSONArray("children");
for(int j = 0; j < fullMenuSections.size(); j++)
{
//I feel like a normal sushi rull so I just want to view that section of the menu
if(fullMenuSections.getJSONObject(j).getString("name").equals("Rolls & Hand Rolls"))
{
JSONArray rolls = fullMenuSections.getJSONObject(j).getJSONArray("children");
for(int k = 0; k < rolls.size(); k++)
{
//I'm craving fish so I'm going to get a spicy tuna roll.
if(rolls.getJSONObject(k).getString("name").equals("Spicy Tuna Roll"))
{
JSONObject spicyTunaRoll = rolls.getJSONObject(k);
JSONArray rollOptions = spicyTunaRoll.getJSONArray("children");
itemId = spicyTunaRoll.getString("id");
quantity = spicyTunaRoll.getInt("max_qty"); //I'm going to add the max quantity so I'm sure I'll be over the order minimum for this merchant.
//Now I'm going to make sure I select any required options for this item
for(int l = 0; l < rollOptions.size(); l++)
{
JSONObject rollOptionGroup = rollOptions.getJSONObject(l);
//Skipping any options that aren't required
if(rollOptionGroup.getInt("min_selection") > 0)
{
JSONArray options = rollOptionGroup.getJSONArray("children");
//I'm going to add the first one, using a minimum required quantity
optionQuantities.put(options.getJSONObject(0).getString("id"), rollOptionGroup.getInt("min_selection"));
}
else
{
continue;
}
}
}
}
}
}
}
}
WebResource resource = Client.create().resource(UriBuilder.fromUri(host + CUSTOMER_CART_URL + "/" + merchantId).clone().build().toASCIIString());
JSONObject formData = new JSONObject();
formData.put("order_type", ORDER_TYPE);
formData.put("client_id", CLIENT_ID);
formData.put("instructions", itemNotes);
String optionKeyToQuantity = "";
for(Map.Entry<String, Integer> option : optionQuantities.entrySet())
optionKeyToQuantity += "\"" + option.getKey() + "\": " + option.getValue() + ",";
String itemJsonString = "{" +
"\"item_id\": \"" + itemId + "\"," +
"\"item_qty\": " + quantity + "," +
"\"option_qty\": {" + optionKeyToQuantity + "}," +
"}";
JSONObject item = JSONObject.fromObject(itemJsonString);
formData.put("item", item.toString());
ClientResponse res = resource.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON)
.header(GUEST_TOKEN, authToken)
.post(ClientResponse.class, formData.toString());
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
return;
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static String viewCart(String guestToken, String accessToken, Integer merchantId, JSONObject address)
{
String url = host + CUSTOMER_CART_URL + "/" + merchantId;
WebResource resource = Client.create()
.resource(UriBuilder.fromUri(url)
.queryParam("client_id", CLIENT_ID)
.queryParam("zip", address.getString("zip_code"))
.queryParam("city", address.getString("city"))
.queryParam("state", address.getString("state"))
.queryParam("latitude", address.getString("latitude"))
.queryParam("longitude", address.getString("longitude"))
.clone().build().toASCIIString());
ClientResponse res = resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.header((guestToken == null) ? AUTH_TOKEN : GUEST_TOKEN, (guestToken == null) ? accessToken : guestToken)
.get(ClientResponse.class);
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
String cart = res.getEntity(String.class);
return cart;
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static String getOrder(String authToken, int orderId)
{
WebResource resource = Client.create().resource(UriBuilder.fromUri(host + ORDER_URL + "/" + orderId).clone().build().toASCIIString());
ClientResponse res = resource.type(MediaType.APPLICATION_JSON).header(AUTH_TOKEN, authToken).get(ClientResponse.class);
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
String order = res.getEntity(String.class);
return order;
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static String viewCCs(final String authToken)
{
String url = host + CC_URL;
WebResource resource = Client.create().resource(UriBuilder.fromUri(url).clone().build().toASCIIString());
ClientResponse res = resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(AUTH_TOKEN, authToken).get(ClientResponse.class);
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
JSONArray ccInfoArray = JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("cards");
if (ccInfoArray.isEmpty())
{
throw new RuntimeException("You need to add a credit card! Rerun me and do that");
} else
{
return ccInfoArray.getJSONObject(0).getString("cc_id");
}
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
private static String checkout(String authToken, float tip, String orderNotes, int ccId, int locationId, int merchantId)
{
WebResource resource = Client.create().resource(UriBuilder.fromUri(host + CHECKOUT_URL + "/" + merchantId + "/checkout").clone().build().toASCIIString());
JSONObject formData = new JSONObject();
formData.put("instructions", orderNotes);
formData.put("tip", tip);
formData.put("location_id", locationId);
formData.put("order_type", "delivery");
JSONArray payments = new JSONArray();
JSONObject payment = new JSONObject();
payment.put("type", "credit_card");
payment.put("id", ccId);
payments.add(payment);
formData.put("payments", payments);
ClientResponse res = resource.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON).header(AUTH_TOKEN, authToken)
.post(ClientResponse.class, formData.toString());
if (res.getStatus() == ClientResponse.Status.OK.getStatusCode())
{
return res.getEntity(String.class);
} else
{
throw new RuntimeException(JSONObject.fromObject(res.getEntity(String.class)).getJSONArray("message").getJSONObject(0).getString("code"));
}
}
}
Disclaimer This java script is NOT production ready. It’s an attempt to post actual code and how it interacts with the food and liquor API. This script searches, adds items to a cart, and places an order.
Prerequisites This script depends on a few jars. They can be downloaded below
Promotion
The promotion endpoint allows users to apply a promotion to their account by putting in a promotion code. This endpoint require an access token in the Authorization HTTP header. Once the promo is applied to the user’s account successfully, the promo will show in the Customer Checkout call’s response.
Apply a Promo
HTTP Request
{
"deal_code":"HU25",
}
POST /customer/promo/deal
Property Name | Type | Description |
---|---|---|
deal_code | String | The promotion code. |
Success Response
{
"deal": {
"name": "Howard University: Get 25% Off Your First Order",
"minimum": 10,
"id": "893564",
"reward": "percent_off",
"value": 25,
"limitType": "dollar_off",
"valueLimit": "dollar_off"
},
"message": [
{
"code": "deal_add_success",
"user_msg": "Sweet! The deal has been added successfully.",
"dev_msg": "Sweet! The deal has been added successfully."
}
]
}
HTTP 200 OK
Bad Response
{
"deal": null,
"message": [
{
"code": "deal_first_only",
"user_msg": "Sorry, but this promotion is for first-time customers only.",
"dev_msg": "Sorry, but this promotion is for first-time customers only."
}
]
}
HTTP 400 Bad Request
Terms of Use and Conditions
API Terms and Conditions
You hereby agree to the following terms and conditions:
Terms of Use
These API Terms and Conditions are in addition to, incorporated into, form part of and are subject to the Terms of Use.
Definitions
All capitalized and defined terms not defined in these API Terms and Conditions are defined in the Terms of Use.
As used in these API Terms and Conditions:
- the term “Acceptance Terms” is defined below in the section titled “Electronic Document”;
- the term “API” means Content consisting of application programming interface, software development libraries, documentation and information related thereto, as any of the foregoing may be modified by us from time to time;
- the term “API User” is defined below in the section titled “API User Application”;
- the term “API User Applications” means your website, mobile site and/or software applications listed in the API User application filled by you using the applicable functionality of the Site or otherwise as specified by us;
- the term “Connectivity” means (i) the connectivity (using the API) between the API User Applications and the Site, and/or (ii) links on the API User Applications to the Site (including the corresponding Delivery.com merchant members’ pages or home page of the Site);
- the term “Delivery.com Marks” mean trade names, trademarks, service marks, logos, slogans and other identifiers of Delivery.com or its affiliates;
- the term “Information” means any and all materials, information, data and content accessible using the API;
- the term “Order” means an order that is placed and paid for (and not cancelled for any reason) at any time during your API User relationship with us by a Site user and that is recognized by our systems to be initiated on the API User Applications using the Connectivity; and
- the term “Right to Use API” is defined below in the section titled “Right to use API”.
API USER APPLICATIONS
To become eligible to receive and use the API and the Information, you need to submit an API User application and agree to these API Terms and Conditions and Terms of Use by using the applicable functionality of the Site or otherwise as specified by us. Once we notify you in writing that your application has been approved, you become an “API User” and your API User relationship with us begins.
RIGHT TO USE API; USE RESTRICTIONS
API User is encouraged to create innovative software applications that enhance and expand the possibilities of online ordering of Site users. However, doing so is subject some inevitable restrictions (☹), as set forth below:
API User is granted a limited, revocable, non-assignable, non-transferable and personal right to, and API User agrees to, use the API and the Information and establish, and thereafter during your API User relationship with us, maintain the Connectivity (“Right to Use API”) solely for the purposes of sending Orders to the Site and/or directing the users of the API User Applications to the Site, in each case, subject to and in compliance with these API Terms and Conditions.
API User agrees to establish and maintain the Connectivity, including by integrating the API User Applications to the Site and/or placing links on the API User Applications to all listings of Delivery.com merchant members on the API User Applications. Such links will direct the users of the API User Applications to the corresponding Delivery.com merchant members’ pages or home page of the Site. API User further agrees to update and maintain the Connectivity using current and accurate Information and Content as made available by Delivery.com from time to time.
Without limiting the foregoing, API User may use the API to develop, implement, test, launch, operate and support software applications that integrate to the Site or to deep link from the API User Applications to the Site, in each case, solely for the purposes of sending Orders to the Site and/or directing the users of the API User Applications to the Site, in each case, subject to and in compliance with these API Terms and Conditions. (As used in these API Terms and Conditions, the phrase “to deep link” means linking in a way that a user of the API User Applications is linked directly to the corresponding merchant member’s pages or home page of the Site.) API User shall ensure that all links to the Site use our logo, as may be provided by us from time to time.
You acknowledge and agree that use of the API for any purposes except for the ones expressly permitted to API User in these API Terms and Conditions is expressly prohibited and that you shall not use the API or the Information for any other purposes, including information gathering for statistical purposes or otherwise. Without limiting the foregoing and in addition thereto, when linking or deep linking users of the API User Applications to the Site, you agree not to use the API or the Information in a way that will make it non obvious to a user of the API User Applications that she/he is leaving the API User Applications and is using the Site.
You further agree:
(i) that the API and the Information are being provided solely for API User’s use as expressly provided herein, and API User shall not permit or facilitate, and shall prevent, any access to or use of the API or the Information and/or any copying, storage, distribution, sub-licensing, disclosure, sale, parsing, manipulation, create(ion) derivative works based on and/or use in any way of the API or Information, in whole or in part except as otherwise expressly permitted in these API Terms and Conditions;
(ii) to provide reasonable cooperation to Delivery.com in the testing of any software, systems, applications, hardware, devices and/or connectivity in connection with the delivery and functionality of the API and the Information; and
(iii) to promptly implement modifications to the software and systems used by or for API User Applications which are reasonable and feasible to accommodate changes as required by Delivery.com so as to enable API User to continue to receive Information using the API. (For the avoidance of doubt, API User is responsible for the API User Applications and for developing the API, establishing and maintaining the Connectivity, receiving and displaying the then current Information on the API User Applications and any and all circuit, equipment and other costs, fees and expenses associated therewith, including marketing, sales and operations (including travel) expenses and the costs associated with API User’s performance of its obligations pursuant to these API Terms and Conditions.)
Except as expressly permitted in these API Terms and Conditions, you shall (i) have no right to and shall not access, store, distribute, display, sub-license, disclose, sell, copy, reproduce, create any derivative works based on and/or use in any way any API or Information; and (ii) not provide, distribute, display or sell the API or Information to any third parties.
API User Applications
API User hereby represents, warrants and agrees that: (a) the API User Applications are (and shall continue to be) owned, operated and/or running software provided by API User; (b) the API User Applications are not and shall not be operated in violation of any applicable federal, state or local laws, rules or regulations; and (c) the API User Applications, the content included on the API User Applications, as well as the operation of the API User Applications, are not and will not (i) misappropriate, violate or infringe the copyright, trademark, trade name, patent, right of publicity or privacy or any proprietary or other right of any entity or person; (ii) breach any agreement, license or other instrument, order, judgment or decree of any court, governmental agency or regulatory body to which API User is bound or (iii) contain any material which is libelous, slanderous or obscene.
API User shall not have the right to and shall not use, publish, share, sell or otherwise distribute any data collected with respect to users of the API User Applications that relates to (A) their clicking on a Delivery.com link, (B) their use of the Site, and/or (iii) any information deemed proprietary by Delivery.com.
USE OF INFORMATION AND MARKS
Any use of the Information and the Delivery.com Marks must comply with any and all reasonable usage guidelines communicated by Delivery.com to API User from time to time. To the extent API User displays any Information on the API User Applications, Company shall attribute such Information to Delivery.com. In addition, API User agrees to include and display in a prominent location of the API User Applications, where applicable, an indication that the software application has been created using the API and/or the Information. Such attribution shall be made by including the phrase “Powered by Delivery.com” or other language agreed by API User and Delivery.com, and may also include Delivery.com logo provided by Delivery.com. API User agrees not to use or exploit any of the Information or the Delivery.com Marks, except in such form as Delivery.com may consent to in writing signed by Delivery.com. API User further agrees not to use any of the Information or the Delivery.com Marks in a false, adverse, poor light or in any way that may be deemed by Delivery.com to be detrimental to its or its business. API User agrees to display Delivery.com trademark and copyright notices or legends provided by Delivery.com to API User from time to time when using Delivery.com Marks and/or Information. Delivery.com and its affiliates reserve all right, title, and interest in and to the Information and the Delivery.com Marks, along with any intellectual property rights associated with any of the foregoing, and no title or ownership of any of the foregoing is transferred to API User or any other entity or person pursuant to these API Terms and Conditions.
COMMISSIONS
Unless as otherwise set forth in a written agreement by and between you and us, in which case such agreement, and not this section titled “Commissions”, shall control and govern your ability to receive commissions, during your API User relationship with us, you may become eligible to receive a certain percentage (in each case, as indicated below) of the total amount of commissions actually received by us from applicable Orders (before tips, taxes and delivery charges) less third party credit and debit card (including university or college issued ones) and other processing and/or transmission fees and charges applicable to such Orders. Such percentage is 25%. You will be eligible to receive payments following the end of each calendar month that your commission balance is US$100.00 or more.
TERMINATION OF THE RIGHT TO USE; CONSEQUENCES OF TERMINATION
You may terminate your API User relationship with us at any time by a written notice to us using the applicable functionality of the Site.
We may terminate your API User relationship with us by a written notice posted on the Site and/or e-mailed or otherwise provided to you at the address in your API User profile on the Site at any time.
In addition, we may terminate your API User relationship with us by a written notice posted on the Site and/or e-mailed or otherwise provided to you at the address in your API User profile on the Site in the event that:
(A) we terminate Right to Use API, in whole or in part;
(B) you violate the Terms of Use and/or these API Terms and Conditions; or
(C) you become subject to investigation or other legal proceeding, or are reported to have engaged in activity of a nature which is reasonably considered by us to have the potential to damage our goodwill, reflect negatively upon our name, reputation or standards, cause a loss of public confidence or other negative consequences.
(For the purposes of sub-section (B) and sub-section (C) above only, the term “you” includes “you” and, where applicable, your affiliates and your and their officers, directors, employees and agents. Termination pursuant to sub-section (B) and/or sub-section (C) above is referred to as termination “for cause”.)
Upon termination of your API User relationship with us, we will have no obligations to you and the rights granted hereunder shall immediately terminate and API User shall have no right to use and shall immediately stop using and destroy the API, Delivery.com Marks and the Information in its possession or control. These API Terms and Conditions and obligations pursuant to these API Terms and Conditions shall become effective upon your submission of the API User application filled by you using the applicable functionality of the Site or otherwise as specified by us, survive termination of your API User relationship with us and shall continue in perpetuity. Notwithstanding the foregoing, in the event that we terminated your API User relationship with us “for cause”, we shall have no further obligation to pay you any commissions whatsoever.
PROVIDING INFORMATION
API User agrees to, from time to time promptly upon request of Delivery.com, provide to Delivery.com (i) a written certification that states that API User, to the best of your knowledge upon reasonable due diligence, is not in breach of these API Terms and Conditions and (ii) any and all information and records reasonably necessary to verify practices of API User related to access to and/or use of the API, Delivery.com Marks and the Information by or through API User.
INDEPENDENT CONTRACTOR STATUS
API User an independent contractor of Delivery.com, and neither API User nor any of API User employees or agents, if any, shall be deemed to be an employee or agent of Delivery.com nor eligible for any of our benefits for any reason. API User shall not, and shall cause API User employees and agents, if any, not to, hold himself/herself/itself or themselves (as applicable) out as, nor claim to be, officers, employees or agents of Delivery.com, and shall ensure that neither API User, nor any or API User employees or agents make claims, demands or applications for any right, privilege or treatment applicable to any officer, director or employee of Delivery.com. API User agrees to take any and all steps necessary to preserve API User’s independent contractor relationship with Delivery.com and non-employment relationship between Delivery.com and API User and API User employees and agents, if any. API User acknowledges and agrees that Delivery.com is not a joint employer, dual-employer, co-employer or single employer of API User or API User employees or agents, if any.
CONFIDENTIALITY; NON-DISPARAGEMENT
You agree that the API, the Information and the list of merchant members, users and customers of Delivery.com are proprietary and confidential to Delivery.com and further agree to (and will cause his/her/its employees and agents, where applicable, to) (i) keep confidential, (ii) not disclose to any third parties, and (iii) not use for any purpose, whatsoever, except as expressly permitted in these API Terms and Conditions, such API and Information. Furthermore, during your API User relationship with us and for a period of one (1) additional year thereafter you agree not to make or participate in the making of any public comments or statements in any media (print, broadcast, electronic or otherwise) that are disparaging regarding Delivery.com, its managers or its senior executive officers, or are otherwise contrary to the interests of Delivery.com.
The use or disclosure of API or any Information in a manner inconsistent with these API Terms and Conditions may cause Delivery.com irreparable damage and Delivery.com shall be entitled to equitable and injunctive relief to prevent such threatened or actual unauthorized use or disclosure. Without limiting the foregoing and in addition thereto, in the event of any breach of these API Terms and Conditions, you agree to promptly disgorge any and all revenue earned by API User or any of API User affiliates arising from use, development, marketing, sale, implementation or exploitation of any portion of API or Information.
As an API User, you agree that, in addition to any other obligations that you may have under the Terms of Use and these API Terms and Conditions:
(A) during your API User relationship with us, not to (and to cause your employees and agents, where applicable, not to) take any action to harm, that harms, or that reasonably could be expected to harm, Delivery.com; and
(B) during your API User relationship with us and for ninety (90) days thereafter, not to, directly or indirectly (and not to enter into any contract, agreement or negotiation with any third party to) advertise, promote, market, provide a link to, display or describe including on the API User Applications any services that, in the reasonable judgment of Delivery.com, compete or may compete with the services provided by Delivery.com.
ELECTRONIC DOCUMENTS
We may, in our sole discretion, seek your consent to these API Terms and Conditions by means of an electronic signature by requesting you to affirmatively check the box indicating your acceptance to these API Terms and Conditions, affirmatively “click” on boxes containing the words “I Accept,” “I Agree” or other similar phrases (collectively, “Acceptance Terms”). If you “click” on the Acceptance Terms, your “click” will be deemed a legally binding electronic signature. You acknowledge and agree that you will carefully review any document or web page before making such an electronic signature.
By electronically indicating your agreement to these API Terms and Conditions, you acknowledge and agree: (i) that you and, where applicable, the company or organization on whose behalf we grant you access to the API intend to form a legally binding contract between you and Delivery.com; (ii) that you have read and agree to the terms and conditions of these API Terms and Conditions; (iii) that you agree and intend that these API Terms and Conditions to be the legal equivalent of signed, written contracts, and equally binding; (iv) that by electronically agreeing to these API Terms and Conditions, you acknowledge that you have received a copy of these API Terms and Conditions and Terms of Use by your viewing a web page containing a hyperlink to the web pages where these API Terms and Conditions and Terms of Use are displayed or otherwise; and (v) that if you are executing these API Terms and Conditions on behalf of others, you hereby certify that you are an authorized representative, duly authorized, including where applicable, by all required corporate action to act on behalf of such others and shall cause such others and their employees and agents to comply with these API Terms and Conditions and Terms of Use as if they were you hereunder.
Version Dated: November, 2016