Papa John's API endpoint
Returns one Papa John's US or Canada menu SKU with that restaurant's price for it, together with the full customization axes of the product group it belongs to: every size and crust the product is sold in, and every preparation instruction with its choices and default. The response also names the category and section the item sits under. Pass a store_id so the price is that restaurant's; omitting it returns the national default price. SKUs come from GET /papajohns/menu.
/papajohns/menu/itemQuery parameters:
sku (required) — a product sku from /papajohns/menu.store_id (optional) — restaurant id from
/papajohns/store or
/papajohns/nearby, so the price is that
restaurant's. Omit for the national default price.Notable response behavior:
group carries every size and crust the product is sold in and every
preparation instruction (how much cheese, how well done) with its choices and
which one is the default. Unlike /papajohns/menu,
these are always included — that is the point of this endpoint.category and section name where the item sits in the menu.sku returns a 404. A sku that upstream prices but does not
display in any menu group also returns a 404, with a message saying so —
it is not orderable from the menu even though a price exists.| Field | In the sample | Value in the sample |
|---|---|---|
| store_id | Has a value | |
| national_default | Has a value | false |
| category | Has a value | “pizza” |
| section | Has a value | “Most Popular” |
| group.id | Has a value | |
| group.title | Has a value | “Pepperoni Pizza” |
| group.description | Has a value | “Pepperoni, cheese and pizza sauce on your choice of crust.” |
| group.image_url | Has a value | papajohns.com |
| group.customizable | Has a value | “full” |
| group.price_from | Has a value | 13.99 |
| group.products | Has a value | 9 entries |
| group.max_toppings | Has a value | 7 |
| group.max_same_topping | Has a value | 2 |
| group.allow_half_toppings | Has a value | true |
| group.available_topping_ids | Has a value | |
| group.sizes | Has a value | 4 entries |
| group.crusts | Has a value | 5 entries |
| group.instructions | Has a value | 4 entries |
| product.sku | Has a value | |
| product.name | Has a value | “10 Inch Original Pepperoni Pizza” |
| product.title | Has a value | “Small Original Crust - Pepperoni” |
| product.size | Has a value | “Small” |
| product.price | Has a value | 13.99 |
| product.regular_price | Has a value | 13.99 |
| product.code | Has a value | |
| product.size_id | Has a value | |
| product.crust_id | Has a value | |
| product.calories | Has a value | 210 |
| product.serving_label | Has a value | “/slice, 6 slices” |
| product.slices | Has a value | 6 |
| product.image_url | Has a value | papajohns.com |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| sku | string | Yes | Product sku from GET /papajohns/menu | 1-1-2-115 | |
| store_id | string | No | Restaurant id from GET /papajohns/store or GET /papajohns/nearby. Omit for the national default price. | 5054 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/papajohns/menu/item?sku=1-1-2-115" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"store_id": 5054,
"national_default": false,
"category": "pizza",
"section": "Most Popular",
"group": {
"id": "cyo",
"title": "Create Your Own Pizza",
"customizable": "full",
"max_toppings": 7,
"allow_half_toppings": true,
"sizes": [
{
"id": 2,
"name": "Small",
"measure": "10\"",
"default": false
},
{
"id": 4,
"name": "Large",
"measure": "14\"",
"default": true
}
],
"crusts": [
{
"id": 1,
"name": "Original Crust",
"code": "PIZZA_ORIGINAL",
"sub_type": "Original",
"default": true
}
],
"instructions": [
{
"id": 2,
"name": "CHEESE",
"description": "How much cheese?",
"choices": [
{
"id": 6,
"name": "Light Cheese",
"code": "ILC"
},
{
"id": 5,
"name": "Regular Cheese",
"default": true
}
]
}
],
"products": []
},
"product": {
"sku": "1-1-2-115",
"name": "10 Inch Original Pepperoni Pizza",
"size": "Small",
"price": 14.99,
"calories": 210,
"serving_label": "/slice, 6 slices",
"slices": 6
},
"source_url": "https://www.papajohns.com/api/trpc/product.getByStore?input={\"json\":{\"storeId\":5054}}",
"fetched_at": "2026-09-06T09:00:00Z"
}
}Request schema
No body schema
Response schema
#/definitions/papajohns.menuItemResponseDoc
| 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.MenuItemResponse | No | ||||
| data.category | string | No | pizza | |||
| data.fetched_at | string | No | ||||
| data.group | object | No | Group is the product group this SKU belongs to, carrying the full customization axes for it. | |||
| data.group.allow_half_toppings | boolean | No | true | |||
| data.group.available_topping_ids | array | No | ||||
| data.group.crusts | array | No | ||||
| data.group.crusts[].code | string | No | PIZZA_ORIGINAL | |||
| data.group.crusts[].default | boolean | No | true | |||
| data.group.crusts[].id | integer | No | 1 | |||
| data.group.crusts[].name | string | No | Original Crust | |||
| data.group.crusts[].sub_type | string | No | Original | |||
| data.group.customizable | string | No | full | Customizable reports how far the product can be customized, as upstream classifies it, e.g. full or none. | ||
| data.group.description | string | No | ||||
| data.group.featured | boolean | No | ||||
| data.group.free_toppings | integer | No | ||||
| data.group.id | string | No | cyo | |||
| data.group.image_url | string | No | ||||
| data.group.instructions | array | No | ||||
| data.group.instructions[].choices | array | No | ||||
| data.group.instructions[].choices[].code | string | No | ILC | |||
| data.group.instructions[].choices[].default | boolean | No | false | |||
| data.group.instructions[].choices[].id | integer | No | 6 | |||
| data.group.instructions[].choices[].name | string | No | Light Cheese | |||
| data.group.instructions[].description | string | No | How much cheese? | |||
| data.group.instructions[].id | integer | No | 2 | |||
| data.group.instructions[].name | string | No | CHEESE | |||
| data.group.max_same_topping | integer | No | 2 | |||
| data.group.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.group.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.group.products | array | No | ||||
| data.group.products[].calories | integer | No | 210 | Calories is per the serving described by serving_label. | ||
| data.group.products[].code | string | No | PR10Q1 | |||
| data.group.products[].crust_id | integer | No | 1 | |||
| data.group.products[].description | string | No | ||||
| data.group.products[].disclaimer | string | No | ||||
| data.group.products[].image_url | string | No | ||||
| data.group.products[].name | string | No | 10 Inch Original Pepperoni Pizza | |||
| data.group.products[].price | number | No | 14.99 | Price is this store's price. A build-your-own SKU whose price depends entirely on the customer's choices reports 0. | ||
| data.group.products[].regular_price | number | No | 14.99 | RegularPrice is the pre-promotion menu price where it differs. | ||
| data.group.products[].serving_label | string | No | /slice, 6 slices | ServingLabel describes what calories are counted per, e.g. "/slice, 6 slices". | ||
| data.group.products[].size | string | No | Small | Size is the size label this SKU represents within its group. | ||
| data.group.products[].size_id | integer | No | 2 | |||
| data.group.products[].sku | string | No | 1-1-2-115 | |||
| data.group.products[].slices | integer | No | 6 | |||
| data.group.products[].surcharge | number | No | ||||
| data.group.products[].title | string | No | Title is the shorter in-menu label, e.g. "Small Original Crust - Pepperoni". | |||
| data.group.sizes | array | No | Sizes, Crusts and Instructions are populated only when include_options=true. | |||
| data.group.sizes[].default | boolean | No | false | |||
| data.group.sizes[].id | integer | No | 2 | |||
| data.group.sizes[].measure | string | No | 10" | Measure is the physical size where the group has one, e.g. 10". | ||
| data.group.sizes[].name | string | No | Small | Name is the size's marketing name, e.g. Small. | ||
| data.group.title | string | No | Create Your Own Pizza | |||
| data.national_default | boolean | No | false | |||
| data.product | papajohns.MenuProduct | No | ||||
| data.product.calories | integer | No | 210 | Calories is per the serving described by serving_label. | ||
| data.product.code | string | No | PR10Q1 | |||
| data.product.crust_id | integer | No | 1 | |||
| data.product.description | string | No | ||||
| data.product.disclaimer | string | No | ||||
| data.product.image_url | string | No | ||||
| data.product.name | string | No | 10 Inch Original Pepperoni Pizza | |||
| data.product.price | number | No | 14.99 | Price is this store's price. A build-your-own SKU whose price depends entirely on the customer's choices reports 0. | ||
| data.product.regular_price | number | No | 14.99 | RegularPrice is the pre-promotion menu price where it differs. | ||
| data.product.serving_label | string | No | /slice, 6 slices | ServingLabel describes what calories are counted per, e.g. "/slice, 6 slices". | ||
| data.product.size | string | No | Small | Size is the size label this SKU represents within its group. | ||
| data.product.size_id | integer | No | 2 | |||
| data.product.sku | string | No | 1-1-2-115 | |||
| data.product.slices | integer | No | 6 | |||
| data.product.surcharge | number | No | ||||
| data.product.title | string | No | Title is the shorter in-menu label, e.g. "Small Original Crust - Pepperoni". | |||
| data.section | string | No | Most Popular | |||
| data.source_url | string | No | ||||
| data.store_id | integer | No | 5054 | |||
| 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/item?sku=1-1-2-115" \
-H "x-api-key: $CRAWLORA_API_KEY"