Endpoint
POST https://www.scale-recipe.com/api/scaleJSON in, JSON out. Content-Type: application/json. CORS is open to all origins, so you can call it from a browser, a Node script, an LLM tool, or any other client.
Request body
{
"ingredients": [
"1 1/2 cups all-purpose flour",
"2 tsp salt",
"3 large eggs"
],
"from": 4,
"to": 6
}Or pass ratiodirectly when you don't have a from/to serving count:
{
"ingredients": ["1 cup butter", "2 cups sugar"],
"ratio": 0.5
}Field reference
ingredients(string[], required) — free-form recipe lines, one per array entry. Quantities can be integers (2), decimals (1.5), slashed fractions (1/2), mixed numbers (1 1/2), Unicode fractions (½,1½), or absent. Up to 200 entries, each ≤ 500 characters.from(number, optional) — original recipe servings. Must be positive.to(number, optional) — target servings. Provide bothfromandtoto compute the ratio automatically.ratio(number, optional) — explicit scaling factor. Use this when you don't have a from/to split. Must be between0.01and100.lang(string, optional) — ISO language code (e.g."es","de") for unit-name translation. Defaults to English. Invalid codes fall back to English.
You must provide either ratio, or both from and to.
Response
{
"ok": true,
"ratio": 1.5,
"scaled": [
"2 1/4 cups all-purpose flour",
"1 tbsp salt",
"4 1/2 large eggs"
]
}Lines without a parseable quantity (instructions accidentally included, ingredient notes like “to taste”) pass through unchanged.
What “smart fractions” means
Scaled quantities are rounded to the closest culinary fraction — denominators of 2, 3, 4, 5, 6, 8, 12, 16 — so the output stays measurable with the cups, spoons, and scales most kitchens own. 0.667 cups becomes 2/3 cup, not 0.667 cups.
What “unit promotion” means
When a scaled quantity crosses a useful unit boundary, the unit promotes:
3 tsp→1 tbsp16 tbsp→1 cup4 cups→1 quart1000 g→1 kg
Promotions only fire when the result is at least one unit of the larger size — a recipe scaled by 1.25× still reads naturally, without forced conversion.
Errors
All errors return JSON of the form { "ok": false, "error": "..." }:
- 400— body wasn't JSON, missing required fields, type mismatch, ratio out of range, or too many ingredients.
- 500 — unexpected server error. If you see this consistently, please tell us with the request body.
Examples
cURL
curl -X POST https://www.scale-recipe.com/api/scale \
-H "Content-Type: application/json" \
-d '{
"ingredients": ["1 1/2 cups flour", "2 tsp salt", "3 large eggs"],
"from": 4,
"to": 6
}'Node / fetch
const res = await fetch("https://www.scale-recipe.com/api/scale", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
ingredients: ["1 1/2 cups flour", "2 tsp salt", "3 large eggs"],
from: 4,
to: 6,
}),
});
const { ok, scaled, ratio, error } = await res.json();Python / requests
import requests
r = requests.post(
"https://www.scale-recipe.com/api/scale",
json={
"ingredients": ["1 1/2 cups flour", "2 tsp salt", "3 large eggs"],
"from": 4,
"to": 6,
},
timeout=10,
)
data = r.json()
print(data["scaled"])Limits and fair use
- Up to 200 ingredient lines per request.
- Each line up to 500 characters.
- Ratio between 0.01 and 100.
- No formal rate limit today. Don't hammer the endpoint — cache responses on your side. If usage gets unsustainable we'll add per-IP limits and document them here first.
- No authentication required. If you build something cool with it, an email or backlink is appreciated but not required.
Machine-readable spec
The API is described by an OpenAPI 3.0 specification (also available as JSON). Drop the spec URL into Postman, Insomnia, Swagger UI, OpenAPI Generator, or any other tool that consumes OpenAPI to get an auto-generated client, mock server, or interactive docs.
For LLM agents and AI assistants, an ai-plugin.json manifest is published at the standard well-known path — pointing at the same OpenAPI spec — so agent frameworks can discover and call the endpoint without manual wiring.
Stability and versioning
This is v1. We treat the request and response shape as a public contract — additive changes only (new optional fields), no breaking renames. If we ever need a breaking change, we'll ship it at /api/v2/scale and keep v1 running for at least 12 months.
Use cases
- Recipe sites that need accurate scaling without writing the math themselves.
- LLM/AI agents that scale recipes for users and want a deterministic, audited engine.
- Meal-prep or grocery-list apps that adjust shopping quantities by household size.
- Cooking-show apps that show different serving counts per viewer.
Questions?
Reach out via the contact page. For details on how the math works and edge cases, see the Journal — particularly the essays on scaling cake bake-times and salt-brand conversion.