Empowering Restaurants through Integration

Follow

After your kickoff call with the Grubhub team, you will be provided with Preproduction credentials to begin development to our API components. You will receive these credentials through a Privnote through your email. Please keep in mind that the link will expire after one-click. Please take care to save these credentials.

Sample Credential Format

Base URL https://api-third-party-gtm-pp.grubhub.com/
Partner Key X
Client ID X
Secret Key X
Issue Date X
Merchant ID(s) 012345670890
Grubhub For Restaurants https://restaurant-pp.grubhub.com/login
Username and Password X
Diner Account and Login Link https://pp.grubhub.com/create-account
Test Credit Card Information Card Number, Exp Date, CVV


API Authorization:

Generating a MAC token (service-to-service authentication):

The following are the steps to create the authorization header for authenticating to a GrubHub

service. The values below are for example only.

 

The request in the example is:

GET https://ghc-1592927976-ot-3pi-pp.grubhub.com/restaurants/search/third_pa
rty/search_listing?facet=open_now:false&locationMode=DELIVERY_OR_PICKUP&
pagesize=20&latitude=40.76501083&longitude=-73.98383332&preciseLocation=
true&sortSetId=umamiv3&sponsoredSize=0&countOmittingTimes=true&facet=703
5ffe0-f4c2-11e8-a467-171e80b5eb77'

with no request body

1. Obtain client credentials including the client ID, secret key, issue date and partner key

client_id: sv:v1:76529290-50af-11e5-bb6b-a737f7aae142

secret_key: PPF9ZCla987/5tAb11KRlQLHf74HCfCPrOx5zTIQdTY=

issue_date: 1441115023929

partner_key: GbxHMKaYEeySYC8iz20QaA

We will use these values in our example.

2. Generate a nonce

Can be any one-time-use secure random value. The Security Authorization Library uses the
seconds between issue date and system date, colon, a random alphanumeric string. You can
use anything that is sufficiently random that would be completely unlikely to be reused, such as
a random UUID.
Example value:
2074341:rcfR0BzN

3. Generate a base64 encoded hash of the request body if it exists, otherwise use an empty string

If there is a request body, use a Basic Base64 encoder that does NOT generate URL-safe

characters, but DOES add padding ("=") (BASIC in https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html)

bodyHash=Base64.getEncoder().encodeToString(DigestUtils.sha256(requestBody));

If there is no request body, empty string

In our example we are signing a GET call, so the body will be empty String

4. Normalize the request

Note:

  • NEW_LINE is "\n"

  • requestPath is the URL path component only. Do NOT include query parameters, fragments or anything else.

  • bodyHash and ext are not optional. If not applicable for a request, use empty strings for those values, not null.

  • port is required, use 443 for https, unless the request is sent to an explicit port number.

Example code:

stringBuilder.append(nonce).append(NEW_LINE)

.append(requestMethod.toUpperCase()).append(NEW_LINE)

.append(requestPath).append(NEW_LINE)

.append(host.toLowerCase()).append(NEW_LINE)

.append(port).append(NEW_LINE)

.append(bodyHash).append(NEW_LINE)

.append(ext).append(NEW_LINE);

normalizedRequest = stringBuilder.build();

Example:

original request path: restaurants/search/third_party/search_listing?facet=open_now:false&locationMode=DELI VERY_OR_PICKUP

requestMethod: GET

requestPath: /restaurants/search/third_party/search_listing (without parameters)

host: ghc-1592927976-ot-3pi-pp.grubhub.com

port: 443

nonce: 2074341:rcfR0BzN

Example value:

2074341:rcfR0BzN\nGET\n/restaurants/search/third_party/search_listing\ng
hc-1592927976-ot-3pi-pp.grubhub.com\n443\n\n\n

(note the three blank lines at the end are required for body hash and ext, even when a GET

request does not contain any body)

5. Hash the normalized request using HMAC SHA256 with the client secret

sha256Hmac = Mac.getInstance(HMAC_SHA256);

secretKeySpec = new SecretKeySpec(secretKey.getBytes(Charsets.UTF_8),
HMAC_SHA256);

sha256Hmac.init(secretKeySpec);

hashedRequest =
sha256Hmac.doFinal(normalizedRequest.getBytes(Charsets.UTF_8));

Example value:

hashedRequest Hex = 2149d9b635a68e10f23022da803b72139f24e6c8e9f8ffc5376b0fcb9ec8ffe1

6. Base64 encode the hashed request

Use a Basic Base64 encoder that does NOT generate URL-safe characters, but DOES add

padding ("=") (BASIC in https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html)

mac = Base64.getEncoder()encodeToString(hashedRequest);

Example value:

mac_signature = IUnZtjWmjhDyMCLagDtyE58k5sjp+P/FN2sPy57I/+E=

7. Create the HTTP "Authorization" header value

Requests with body must supply bodyHash in Authorization header.

Example value:

MAC
id="sv:v1:76529290-50af-11e5-bb6b-a737f7aae142",nonce="2074341:rcfR0BzN"
,mac="+uJ742k6I3KsrO7rEtF7RT+3980YjEmghujCFry3tVQ="

Example of header with body hash, for this example we use the body="hello=world%21"

MAC
id="sv:v1:76529290-50af-11e5-bb6b-a737f7aae142",nonce="2074341:rcfR0BzN"
,bodyhash="Z49JCJwhZyqL6ZBRQiZkF+oazFM4DcqCT3s/uYpPsik=",mac="+uJ742k6I3
KsrO7rEtF7RT+3980YjEmghujCFry3tVQ="

8. Send the HTTP header with the request

Example Value:

Authorization: MAC
id="sv:v1:76529290-50af-11e5-bb6b-a737f7aae142",nonce="2074341:rcfR0BzN"
,mac="IUnZtjWmjhDyMCLagDtyE58k5sjp+P/FN2sPy57I/+E="
Putting it all together:
Sample Request including Grubhub Partner Key Header
curl --location --request GET
'https://ghc-1592927976-ot-3pi-pp.grubhub.com/restaurants/search/third_p
arty/search_listing?facet=open_now:false&locationMode=DELIVERY_OR_PICKUP
&pagesize=20&latitude=40.76501083&longitude=-73.98383332&preciseLocation
=true&sortSetId=umamiv3&sponsoredSize=0&countOmittingTimes=true&facet=70
35ffe0-f4c2-11e8-a467-171e80b5eb77' \

--header 'Authorization: MAC
id="sv:v1:76529290-50af-11e5-bb6b-a737f7aae142",nonce="2074341:rcfR0BzN"
,mac="IUnZtjWmjhDyMCLagDtyE58k5sjp+P/FN2sPy57I/+E="'
--header 'X-GH-PARTNER-KEY: GbxHMKaYEeySYC8iz20QaA'\

API Documentation:

We suggest you build in the following order:

  1. Menus - Build to Normalized Menu structure, then ingesting menu through menuingestion endpoint
    1. Menu Payload Example
    2. Restaurant Menu Image Specifications
  2. Merchant Data

  3. Merchant Schedules

  4. Orders

  5. Webhooks

  6. POS Validation