{"id":"recipe-scale","title":"Recipe scaling with caller-declared non-linear rules","description":"Scales up to 60 ingredient quantities by a servings ratio or a factor for an agent resizing a recipe or batch formula, applying per-ingredient rules the caller declares: linear (the labelled default), power exponent, fixed amounts, min/max clamps and rounding steps, with an optional display unit via unit-convert. Reports what rounding did (relative drift, rounds-to-zero). It does NOT know which ingredients should scale non-linearly (spices, leavening, salt, frying oil): no culinary constants are built in, so those rules and any densities come from the caller. It does not judge taste, safety or baking chemistry.","roi":"Doubling or halving a recipe linearly is the default mistake; this applies the caller's own exceptions exactly and shows the rounding damage. 60 ingredients per $0.005 call.","audience":"business","package":"creative-games-kit","channels":["x402","mcp"],"endpoint":{"method":"POST","url":"https://agents.writerslogic.com/api/v1/recipe-scale","path":"/api/v1/recipe-scale","contentType":"application/json"},"price":{"amount":"0.005","currency":"USDC","network":"base","perCall":true,"failedCallsCharged":false},"inputSchema":{"type":"object","additionalProperties":false,"required":["ingredients"],"properties":{"ingredients":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["name","quantity","unit"],"properties":{"name":{"type":"string","maxLength":80,"description":"Ingredient name, echoed back."},"quantity":{"type":"number","description":"Quantity in the recipe as written.","minimum":1e-9,"maximum":1000000000},"unit":{"type":"string","maxLength":40,"description":"Unit of the quantity: a unit-convert expression (g, cup_us, tbsp_metric) or any counted unit (egg, clove) that is only scaled, never converted."},"rule":{"type":"string","enum":["linear","power","fixed"],"description":"How the quantity scales. Default linear (quantity x factor): the labelled default, not a culinary claim. power: quantity x factor^exponent. fixed: stays at fixedQuantity (or the written quantity)."},"exponent":{"type":"number","description":"Exponent for rule power, caller-supplied (no culinary constants are built in).","minimum":0,"maximum":2},"fixedQuantity":{"type":"number","description":"Quantity for rule fixed. Defaults to the written quantity.","minimum":0,"maximum":1000000000},"min":{"type":"number","description":"Lower clamp applied after the rule.","minimum":0,"maximum":1000000000},"max":{"type":"number","description":"Upper clamp applied after the rule.","minimum":0,"maximum":1000000000},"roundTo":{"type":"number","description":"Round to a multiple of this step (0.25 cup, 1 egg).","minimum":0.000001,"maximum":1000000},"roundMode":{"type":"string","enum":["nearest","up","down"],"description":"Default nearest, ties up."},"displayUnit":{"type":"string","maxLength":40,"description":"Also report the scaled quantity in this unit (needs a density to cross mass and volume)."},"density":{"type":"object","additionalProperties":false,"required":["value","unit"],"properties":{"value":{"type":"number","minimum":1e-9,"maximum":1000000000,"description":"Caller-supplied mass per volume. Never looked up: no ingredient density table is shipped."},"unit":{"type":"string","maxLength":40,"description":"Mass per volume unit expression, e.g. g/mL, kg/m3, lb/ft3, oz/cup_us."}},"description":"Per-ingredient density for displayUnit, overriding the top-level one."},"claimed":{"type":"number","description":"Optional claimed scaled quantity (after rounding); a mismatch fails.","minimum":0,"maximum":1000000000000},"relTolerance":{"type":"number","description":"Relative tolerance for claimed. Default 1e-9.","minimum":0,"maximum":1}}},"maxItems":60,"minItems":1,"description":"Ingredients with quantity, unit and optional scaling rule."},"fromServings":{"type":"number","description":"Servings the recipe is written for.","minimum":0.000001,"maximum":1000000},"toServings":{"type":"number","description":"Servings wanted.","minimum":0.000001,"maximum":1000000},"factor":{"type":"number","description":"Scale factor, instead of fromServings/toServings.","minimum":0.001,"maximum":1000},"density":{"type":"object","additionalProperties":false,"required":["value","unit"],"properties":{"value":{"type":"number","minimum":1e-9,"maximum":1000000000,"description":"Caller-supplied mass per volume. Never looked up: no ingredient density table is shipped."},"unit":{"type":"string","maxLength":40,"description":"Mass per volume unit expression, e.g. g/mL, kg/m3, lb/ft3, oz/cup_us."}},"description":"Default density for displayUnit conversions that cross mass and volume."},"maxRelativeDrift":{"type":"number","description":"Fail an ingredient when rounding moves it by more than this fraction (0.1 = 10%).","minimum":0,"maximum":10}}},"resultSchema":{"type":"object","properties":{"status":{"type":"string","enum":["pass","fail","unknown","unsupported"],"description":"pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass."},"factor":{"type":"string","description":"Scale factor used, 12 significant digits."},"factorBasis":{"type":"string"},"ingredients":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail","unknown","unsupported"]},"rule":{"type":"string","description":"Rule applied, with (default) when the caller named none."},"unit":{"type":"string"},"original":{"type":"number"},"unrounded":{"type":"number","description":"After the rule and clamps, before rounding."},"scaled":{"type":"number","description":"Final quantity after rounding."},"rounded":{"type":"boolean"},"relativeDrift":{"type":"number","description":"|scaled - unrounded| / unrounded."},"clamp":{"type":"string","enum":["min","max"]},"display":{"type":"object","properties":{"quantity":{"type":"string"},"unit":{"type":"string"}}},"reason":{"type":"string"},"message":{"type":"string"},"candidates":{"type":"array","items":{"type":"string"}}}}},"witnesses":{"type":"array","items":{"type":"object","properties":{"ruleId":{"type":"string"},"detail":{"type":"string"},"path":{"type":"string","description":"JSON pointer or dotted path into the input."},"offset":{"type":"integer"},"index":{"type":"integer"},"expected":{"description":"What the rule required."},"actual":{"description":"What the input had."}}}},"versions":{"type":"object","description":"Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile)."},"limits":{"type":"array","items":{"type":"string"}},"deterministic":{"type":"boolean","description":"Always true: pure code, no model."}}},"outputSchema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["pass","fail","unknown","unsupported"],"description":"pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass."},"factor":{"type":"string","description":"Scale factor used, 12 significant digits."},"factorBasis":{"type":"string"},"ingredients":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail","unknown","unsupported"]},"rule":{"type":"string","description":"Rule applied, with (default) when the caller named none."},"unit":{"type":"string"},"original":{"type":"number"},"unrounded":{"type":"number","description":"After the rule and clamps, before rounding."},"scaled":{"type":"number","description":"Final quantity after rounding."},"rounded":{"type":"boolean"},"relativeDrift":{"type":"number","description":"|scaled - unrounded| / unrounded."},"clamp":{"type":"string","enum":["min","max"]},"display":{"type":"object","properties":{"quantity":{"type":"string"},"unit":{"type":"string"}}},"reason":{"type":"string"},"message":{"type":"string"},"candidates":{"type":"array","items":{"type":"string"}}}}},"witnesses":{"type":"array","items":{"type":"object","properties":{"ruleId":{"type":"string"},"detail":{"type":"string"},"path":{"type":"string","description":"JSON pointer or dotted path into the input."},"offset":{"type":"integer"},"index":{"type":"integer"},"expected":{"description":"What the rule required."},"actual":{"description":"What the input had."}}}},"versions":{"type":"object","description":"Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile)."},"limits":{"type":"array","items":{"type":"string"}},"deterministic":{"type":"boolean","description":"Always true: pure code, no model."}}},"_provenance":{"type":"object","description":"C2PA-aligned manifest and W3C VC 2.0 (eddsa-jcs-2022) issued by the hub DID; verify at POST /api/v1/verify-provenance"}},"required":["data","_provenance"]},"example":{"fromServings":4,"toServings":6,"ingredients":[{"name":"flour","quantity":240,"unit":"g"},{"name":"eggs","quantity":2,"unit":"each","roundTo":1},{"name":"chili flakes","quantity":1,"unit":"tsp_metric","rule":"power","exponent":0.5}]},"openapiOperation":{"operationId":"recipe_scale","summary":"Recipe scaling with caller-declared non-linear rules","description":"Scales up to 60 ingredient quantities by a servings ratio or a factor for an agent resizing a recipe or batch formula, applying per-ingredient rules the caller declares: linear (the labelled default), power exponent, fixed amounts, min/max clamps and rounding steps, with an optional display unit via unit-convert. Reports what rounding did (relative drift, rounds-to-zero). It does NOT know which ingredients should scale non-linearly (spices, leavening, salt, frying oil): no culinary constants are built in, so those rules and any densities come from the caller. It does not judge taste, safety or baking chemistry.\n\nPrice: 0.005 USDC on Base (x402).","x-x402-price-usdc":"0.005","x-x402-amount":"5000","x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.005"}},"x-audience":"business","x-sample-url":"https://agents.writerslogic.com/api/v1/samples/recipe-scale","security":[{"x402":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["ingredients"],"properties":{"ingredients":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["name","quantity","unit"],"properties":{"name":{"type":"string","maxLength":80,"description":"Ingredient name, echoed back."},"quantity":{"type":"number","description":"Quantity in the recipe as written.","minimum":1e-9,"maximum":1000000000},"unit":{"type":"string","maxLength":40,"description":"Unit of the quantity: a unit-convert expression (g, cup_us, tbsp_metric) or any counted unit (egg, clove) that is only scaled, never converted."},"rule":{"type":"string","enum":["linear","power","fixed"],"description":"How the quantity scales. Default linear (quantity x factor): the labelled default, not a culinary claim. power: quantity x factor^exponent. fixed: stays at fixedQuantity (or the written quantity)."},"exponent":{"type":"number","description":"Exponent for rule power, caller-supplied (no culinary constants are built in).","minimum":0,"maximum":2},"fixedQuantity":{"type":"number","description":"Quantity for rule fixed. Defaults to the written quantity.","minimum":0,"maximum":1000000000},"min":{"type":"number","description":"Lower clamp applied after the rule.","minimum":0,"maximum":1000000000},"max":{"type":"number","description":"Upper clamp applied after the rule.","minimum":0,"maximum":1000000000},"roundTo":{"type":"number","description":"Round to a multiple of this step (0.25 cup, 1 egg).","minimum":0.000001,"maximum":1000000},"roundMode":{"type":"string","enum":["nearest","up","down"],"description":"Default nearest, ties up."},"displayUnit":{"type":"string","maxLength":40,"description":"Also report the scaled quantity in this unit (needs a density to cross mass and volume)."},"density":{"type":"object","additionalProperties":false,"required":["value","unit"],"properties":{"value":{"type":"number","minimum":1e-9,"maximum":1000000000,"description":"Caller-supplied mass per volume. Never looked up: no ingredient density table is shipped."},"unit":{"type":"string","maxLength":40,"description":"Mass per volume unit expression, e.g. g/mL, kg/m3, lb/ft3, oz/cup_us."}},"description":"Per-ingredient density for displayUnit, overriding the top-level one."},"claimed":{"type":"number","description":"Optional claimed scaled quantity (after rounding); a mismatch fails.","minimum":0,"maximum":1000000000000},"relTolerance":{"type":"number","description":"Relative tolerance for claimed. Default 1e-9.","minimum":0,"maximum":1}}},"maxItems":60,"minItems":1,"description":"Ingredients with quantity, unit and optional scaling rule."},"fromServings":{"type":"number","description":"Servings the recipe is written for.","minimum":0.000001,"maximum":1000000},"toServings":{"type":"number","description":"Servings wanted.","minimum":0.000001,"maximum":1000000},"factor":{"type":"number","description":"Scale factor, instead of fromServings/toServings.","minimum":0.001,"maximum":1000},"density":{"type":"object","additionalProperties":false,"required":["value","unit"],"properties":{"value":{"type":"number","minimum":1e-9,"maximum":1000000000,"description":"Caller-supplied mass per volume. Never looked up: no ingredient density table is shipped."},"unit":{"type":"string","maxLength":40,"description":"Mass per volume unit expression, e.g. g/mL, kg/m3, lb/ft3, oz/cup_us."}},"description":"Default density for displayUnit conversions that cross mass and volume."},"maxRelativeDrift":{"type":"number","description":"Fail an ingredient when rounding moves it by more than this fraction (0.1 = 10%).","minimum":0,"maximum":10}}},"example":{"fromServings":4,"toServings":6,"ingredients":[{"name":"flour","quantity":240,"unit":"g"},{"name":"eggs","quantity":2,"unit":"each","roundTo":1},{"name":"chili flakes","quantity":1,"unit":"tsp_metric","rule":"power","exponent":0.5}]}}}},"responses":{"200":{"description":"Paid result with provenance","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["pass","fail","unknown","unsupported"],"description":"pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass."},"factor":{"type":"string","description":"Scale factor used, 12 significant digits."},"factorBasis":{"type":"string"},"ingredients":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail","unknown","unsupported"]},"rule":{"type":"string","description":"Rule applied, with (default) when the caller named none."},"unit":{"type":"string"},"original":{"type":"number"},"unrounded":{"type":"number","description":"After the rule and clamps, before rounding."},"scaled":{"type":"number","description":"Final quantity after rounding."},"rounded":{"type":"boolean"},"relativeDrift":{"type":"number","description":"|scaled - unrounded| / unrounded."},"clamp":{"type":"string","enum":["min","max"]},"display":{"type":"object","properties":{"quantity":{"type":"string"},"unit":{"type":"string"}}},"reason":{"type":"string"},"message":{"type":"string"},"candidates":{"type":"array","items":{"type":"string"}}}}},"witnesses":{"type":"array","items":{"type":"object","properties":{"ruleId":{"type":"string"},"detail":{"type":"string"},"path":{"type":"string","description":"JSON pointer or dotted path into the input."},"offset":{"type":"integer"},"index":{"type":"integer"},"expected":{"description":"What the rule required."},"actual":{"description":"What the input had."}}}},"versions":{"type":"object","description":"Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile)."},"limits":{"type":"array","items":{"type":"string"}},"deterministic":{"type":"boolean","description":"Always true: pure code, no model."}}},"_provenance":{"type":"object","description":"C2PA-aligned manifest and W3C VC 2.0 (eddsa-jcs-2022) issued by the hub DID; verify at POST /api/v1/verify-provenance"}},"required":["data","_provenance"]}}}},"400":{"description":"Invalid request (no payment consumed)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}},"401":{"description":"Invalid X-API-KEY","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}},"402":{"description":"Payment required or invalid","content":{"application/json":{"schema":{"type":"object","description":"x402 v2 PaymentRequired (also base64 in the PAYMENT-REQUIRED header)","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"code":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}},"extensions":{"type":"object"}}}}}},"502":{"description":"Upstream failure; the payment is released or not settled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}}}},"links":{"docs":"https://agents.writerslogic.com/docs/recipe-scale/","docsJson":"https://agents.writerslogic.com/docs/recipe-scale.json","sample":"https://agents.writerslogic.com/api/v1/samples/recipe-scale","openapi":"https://agents.writerslogic.com/openapi.json","catalog":"https://agents.writerslogic.com/api/v1/catalog","verifyProvenance":"https://agents.writerslogic.com/api/v1/verify-provenance","index":"https://agents.writerslogic.com/docs/index.json"}}