Papa John's API endpoint
Returns a Papa John's US or Canada restaurant's full menu with that restaurant's own prices. Prices are per restaurant, not national -- the same 14-inch pizza can differ by several dollars between two stores -- so pass a store_id from GET /papajohns/store or GET /papajohns/nearby. Omitting it returns the national default menu, flagged as national_default in the response. Each category is returned with its sections and product groups, and every orderable SKU carries its price, calories, serving size, slice count and image. Set include_options to also get each product group's customization axes: every size and crust it is sold in, and every preparation instruction (how much cheese, how well done) with its choices. This is the US and Canada menu -- for India use GET /papajohns/india/menu, and for Chile, Costa Rica, Guatemala, Panama, Portugal or Spain use GET /papajohns/intl/menu.
/papajohns/menuPrices are per restaurant, not national. The same 14-inch pizza can differ by several dollars between two stores. Pass a
store_idfrom/papajohns/storeor/papajohns/nearby.For India use
/papajohns/india/menu; for Chile, Costa Rica, Guatemala, Panama, Portugal or Spain use/papajohns/intl/menu.
Query parameters:
store_id (optional) — restaurant id from
/papajohns/store or
/papajohns/nearby. Omit for the national default
menu.category (optional) — return only one category. One of dippingsauces,
desserts, drinks, extras, papabowls, pizza, sandwiches, sides,
wings.include_options (optional, default false) — include each product group's
sizes, crusts, and preparation instructions.Notable response behavior:
national_default is true when no store_id was supplied, so a caller can
always tell the fallback menu from a real restaurant's prices.price, calories,
serving_label, slices and an image. price_from on a group is its
cheapest priced SKU.price 0; read the group's size and crust options instead.available_topping_ids are upstream's own numeric topping ids. This upstream
publishes no names for them, so they are exposed as ids rather than invented
labels; max_toppings, max_same_topping and allow_half_toppings give the
rules that go with them.category or a negative/non-numeric store_id returns a 400; a
store_id the upstream has no menu for returns a 404.| Field | Filled in, of 1 checked | Values in the sample |
|---|---|---|
| id | 1 | |
| name | 1 | “Pizza” |
| image_url | 1 | papajohns.com |
| sections | 1 | median 6 entries |
| product_count | 1 | 134 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| store_id | string | No | Restaurant id from GET /papajohns/store or GET /papajohns/nearby. Omit for the national default menu. | 5054 | |
| category | string | No | Return only one category. One of: dippingsauces, desserts, drinks, extras, papabowls, pizza, sandwiches, sides, wings Allowed values: dippingsauces, desserts, drinks, extras, papabowls, pizza, sandwiches, sides, wings. | pizza | |
| include_options | boolean | No | Include each product group's sizes, crusts and preparation instructions. Default false. | false | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/papajohns/menu?category=dippingsauces&include_options=true" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"store_id": 5054,
"national_default": false,
"categories": [
{
"id": "pizza",
"name": "Pizza",
"sections": [
{
"id": "most_popular",
"name": "Most Popular",
"product_groups": [
{
"id": "cyo",
"title": "Create Your Own Pizza",
"description": "Build your own custom pizza and we'll handcraft it for you.",
"customizable": "full",
"price_from": 14.99,
"max_toppings": 7,
"max_same_topping": 2,
"allow_half_toppings": true,
"products": [
{
"sku": "1-1-2-115",
"name": "10 Inch Original Pepperoni Pizza",
"title": "Small Original Crust - Pepperoni",
"size": "Small",
"price": 14.99,
"regular_price": 14.99,
"code": "PR10Q1",
"size_id": 2,
"crust_id": 1,
"calories": 210,
"serving_label": "/slice, 6 slices",
"slices": 6
}
]
}
]
}
],
"product_count": 96
}
],
"product_count": 206,
"source_url": "https://www.papajohns.com/api/trpc/menuCategory.getByStore?input={\"json\":{\"storeId\":5054}}",
"fetched_at": "2026-09-06T09:00:00Z"
}
}Request schema
No body schema
Response schema
#/definitions/papajohns.menuResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | Code is the HTTP status code or a custom code used to indicate the result of the request @example 200 | |||
| data | papajohns.MenuResponse | No | ||||
| data.categories | array | No | ||||
| data.categories[].id | string | No | pizza | |||
| data.categories[].image_url | string | No | ||||
| data.categories[].name | string | No | Pizza | |||
| data.categories[].product_count | integer | No | 96 | ProductCount is how many priced SKUs this category contains. | ||
| data.categories[].sections | array | No | ||||
| data.categories[].sections[].description | string | No | ||||
| data.categories[].sections[].id | string | No | most_popular | |||
| data.categories[].sections[].name | string | No | Most Popular | |||
| data.categories[].sections[].product_groups | array | No | ||||
| data.categories[].sections[].product_groups[].allow_half_toppings | boolean | No | true | |||
| data.categories[].sections[].product_groups[].available_topping_ids | array | No | ||||
| data.categories[].sections[].product_groups[].crusts | array | No | MenuCrust record, 5 fields: code, default, id, name, sub_type. Described under Papa John's Menu Item API. | |||
| data.categories[].sections[].product_groups[].customizable | string | No | full | Customizable reports how far the product can be customized, as upstream classifies it, e.g. full or none. | ||
| data.categories[].sections[].product_groups[].description | string | No | ||||
| data.categories[].sections[].product_groups[].featured | boolean | No | ||||
| data.categories[].sections[].product_groups[].free_toppings | integer | No | ||||
| data.categories[].sections[].product_groups[].id | string | No | cyo | |||
| data.categories[].sections[].product_groups[].image_url | string | No | ||||
| data.categories[].sections[].product_groups[].instructions | array | No | MenuInstruction record, 8 fields: choices, description, id, name. Described under Papa John's Menu Item API. | |||
| data.categories[].sections[].product_groups[].max_same_topping | integer | No | 2 | |||
| data.categories[].sections[].product_groups[].max_toppings | integer | No | 7 | Topping rules. AvailableToppingIDs are upstream's own numeric ids; this API publishes no name for them, so they are exposed as ids rather than invented labels. | ||
| data.categories[].sections[].product_groups[].price_from | number | No | 14.99 | PriceFrom is the cheapest priced SKU in the group, so a caller can rank products without walking every SKU. | ||
| data.categories[].sections[].product_groups[].products | array | No | MenuProduct record, 16 fields: calories, code, crust_id, description, disclaimer, image_url, name, price, regular_price, serving_label, size, size_id and 4 more. Described under Papa John's Menu Item API. | |||
| data.categories[].sections[].product_groups[].sizes | array | No | Sizes, Crusts and Instructions are populated only when include_options=true. MenuSize record, 4 fields: default, id, measure, name. Described under Papa John's Menu Item API. | |||
| data.categories[].sections[].product_groups[].title | string | No | Create Your Own Pizza | |||
| data.category | string | No | pizza | |||
| data.fetched_at | string | No | ||||
| data.national_default | boolean | No | false | NationalDefault is true when no store was selected, so a caller can tell a real store's prices from the fallback menu. | ||
| data.product_count | integer | No | 206 | |||
| data.source_url | string | No | ||||
| data.store_id | integer | No | 5054 | StoreID echoes the restaurant the prices belong to. 0 is the national default menu. | ||
| msg | unknown | No | Msg is the message that describes the result of the request @example "Request successful" |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 404 | Not Found | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/papajohns/menu?category=dippingsauces&include_options=true" \
-H "x-api-key: $CRAWLORA_API_KEY"