Starbucks API endpoint
Recalculates calories, fat, sugars, and protein for a customized build of a Starbucks beverage: swap the milk, change the number of espresso shots or syrup pumps, and get the real figures for that exact drink rather than the standard recipe. Starbucks only offers this for four hot espresso beverages; product_number and form must be one of 406/hot (Caffe Americano), 407/hot (Caffe Latte), 408/hot (Caffe Mocha), or 413/hot (Caramel Macchiato). Any other product returns an invalid-parameter error naming the four that work. size_sku comes from a /starbucks/product result's sizes[].sku. modifiers is the COMPLETE build, not a change-set: start from that size's default_recipe, adjust what you want, and send the whole list back; an empty list is rejected. Each modifier needs a sku, an optional quantity (defaults to 1, and is the dial that matters for countable modifiers like espresso shots), and an optional replaced_sku when substituting a pick-one slot such as the milk. This returns Starbucks' own four-value dynamic-nutrition panel, which is smaller than the full per-size panel /starbucks/product returns for the standard build.
/starbucks/product/{product_number}/{form}/nutritionThis endpoint is POST (it takes a JSON body).
Path parameters:
product_number is required. Starbucks limits this feature to four products, so it must be one of 406, 407, 408, 413.form is required and must be hot.The four supported product/form pairs are:
| Product | Path |
|---|---|
| Caffè Americano | 406/hot |
| Caffè Latte | 407/hot |
| Caffè Mocha | 408/hot |
| Caramel Macchiato | 413/hot |
Any other product returns an invalid-parameter error naming these four. This is Starbucks' own limit, not this API's — the upstream returns an opaque server error for anything else.
Body parameters:
size_sku is required. Take it from a /starbucks/product result's sizes[].sku.modifiers is required and must not be empty. It is the complete build, not a change-set: start from that size's default_recipe (also returned by /starbucks/product), adjust what you want, and send the whole list back.market is optional, one of us or ca, defaults to us.Each entry in modifiers takes:
sku (required) — from a size's default_recipe[].sku, or from an option in the product's own options tree for a substitution.quantity (optional, defaults to 1) — the dial that actually moves the numbers for countable modifiers, i.e. those whose default_recipe[].form_code is qty (espresso shots, syrup pumps).replaced_sku (optional) — the default modifier this one substitutes, when swapping a pick-one slot such as the milk.Notable response behavior:
values is Starbucks' own four-value dynamic-nutrition panel (calories, fat, sugars, protein). It is deliberately smaller than the full per-size panel /starbucks/product returns for the standard build, so the two endpoints complement each other rather than overlap.modifiers is echoed back with defaults applied, so the response records exactly which build produced the figures.Example request:
{
"size_sku": "93",
"modifiers": [
{"sku": "55", "quantity": 6},
{"sku": "11010168", "quantity": 1}
]
}
| Field | Filled in, of 4 checked | Values in the sample |
|---|---|---|
| key | 4 | |
| name | 4 | “Calories” and 3 other values |
| value | 4 | 0 to 25, median 0 |
| unit_of_measure | 4 | g (3), kcal (1) |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| product_number (path) | string | Yes | Starbucks numeric product id. One of: 406, 407, 408, 413 | 406 | |
| form (path) | string | Yes | Product form. Only hot is supported for this endpoint Allowed values: hot. | hot | |
| request (body) | object | Yes | The size and the complete modifier build | ||
| x-api-key (header) | string | Yes | API key required |
curl -X POST "https://api.crawlora.net/api/v1/starbucks/product/406/hot/nutrition" \
-H "x-api-key: $CRAWLORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"form":"hot","market":"us","modifiers":[{"quantity":3,"replaced_sku":"string","sku":"55"}],"product_number":"406","size_sku":"93"}'{
"form": "hot",
"market": "us",
"modifiers": [
{
"quantity": 3,
"replaced_sku": "string",
"sku": "55"
}
],
"product_number": "406",
"size_sku": "93"
}{
"code": 200,
"msg": "OK",
"data": {
"market": "us",
"product_number": "406",
"form": "hot",
"size_sku": "93",
"modifiers": [
{
"sku": "55",
"quantity": 6
},
{
"sku": "11010168",
"quantity": 1
}
],
"values": [
{
"key": "calories",
"name": "Calories",
"value": "25",
"unit_of_measure": "kcal"
},
{
"key": "fat",
"name": "Fat",
"value": "0",
"unit_of_measure": "g"
},
{
"key": "protein",
"name": "Protein",
"value": "2",
"unit_of_measure": "g"
},
{
"key": "sugars",
"name": "Sugars",
"value": "0",
"unit_of_measure": "g"
}
]
}
}Request schema
#/definitions/starbucks.NutritionOption
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| form | string | No | hot | |||
| market | string | No | us | Market selects which country site answers. Defaults to us. | ||
| modifiers | array | No | Modifiers is the COMPLETE build, not a delta from the default. Start from the size's default_recipe (returned by /starbucks/product), change what you want, and send the whole list back. An empty list is rejected by Starbucks with "Modifiers list required". | |||
| modifiers[].quantity | integer | No | 3 | Quantity is how many of this modifier. Defaults to 1. For countable modifiers (formCode "qty" -- espresso shots, syrup pumps) this is the dial that actually moves the numbers. | ||
| modifiers[].replaced_sku | string | No | ReplacedSKU is the default modifier this one substitutes, when the caller is swapping a pick-one slot such as the milk. Leave empty for a modifier that is not replacing anything. | |||
| modifiers[].sku | string | No | 55 | SKU is the modifier's sku, from a product size's default_recipe[].sku or from an option in the product's options tree (e.g. a different milk). | ||
| product_number | string | No | 406 | ProductNumber and Form identify the product. Only the four combinations in dynamicNutritionProducts are supported upstream. | ||
| size_sku | string | No | 93 | SizeSKU is the sku of the size being built, from a /starbucks/product result's sizes[].sku. |
Response schema
#/definitions/starbucks.nutritionResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | starbucks.NutritionResponse | No | ||||
| data.fetched_at | string | No | ||||
| data.form | string | No | ||||
| data.market | string | No | ||||
| data.modifiers | array | No | ||||
| data.modifiers[].quantity | integer | No | 3 | Quantity is how many of this modifier. Defaults to 1. For countable modifiers (formCode "qty" -- espresso shots, syrup pumps) this is the dial that actually moves the numbers. | ||
| data.modifiers[].replaced_sku | string | No | ReplacedSKU is the default modifier this one substitutes, when the caller is swapping a pick-one slot such as the milk. Leave empty for a modifier that is not replacing anything. | |||
| data.modifiers[].sku | string | No | 55 | SKU is the modifier's sku, from a product size's default_recipe[].sku or from an option in the product's options tree (e.g. a different milk). | ||
| data.product_number | string | No | ||||
| data.size_sku | string | No | ||||
| data.source_url | string | No | ||||
| data.values | array | No | ||||
| data.values[].key | string | No | ||||
| data.values[].name | string | No | ||||
| data.values[].unit_of_measure | string | No | ||||
| data.values[].value | string | No | ||||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/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 POST "https://api.crawlora.net/api/v1/starbucks/product/406/hot/nutrition" \
-H "x-api-key: $CRAWLORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"form":"hot","market":"us","modifiers":[{"quantity":3,"replaced_sku":"string","sku":"55"}],"product_number":"406","size_sku":"93"}'