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
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="
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:
- Menus - Build to Normalized Menu structure, then ingesting menu through menuingestion endpoint
-
Merchant Data
-
Merchant Schedules
-
Orders
-
Webhooks
- POS Validation