{
  "openapi": "3.0.3",
  "info": {
    "title": "ScaleRecipe API",
    "description": "Free public API for scaling recipe ingredient quantities with smart culinary fractions and unit promotion. Same engine that powers the on-site scaler at https://www.scale-recipe.com/scaler.\n\nNo authentication. Open CORS. Up to 200 ingredient lines per request.",
    "version": "1.0.0",
    "contact": {
      "name": "ScaleRecipe Support",
      "email": "support@scale-recipe.com",
      "url": "https://www.scale-recipe.com/contact"
    },
    "license": {
      "name": "Free for any use (commercial or non-commercial)",
      "url": "https://www.scale-recipe.com/terms"
    },
    "termsOfService": "https://www.scale-recipe.com/terms",
    "x-logo": {
      "url": "https://www.scale-recipe.com/icon.png",
      "altText": "ScaleRecipe logo"
    }
  },
  "servers": [
    { "url": "https://www.scale-recipe.com", "description": "Production" }
  ],
  "externalDocs": {
    "description": "Full developer documentation with examples",
    "url": "https://www.scale-recipe.com/developers"
  },
  "tags": [
    { "name": "Scaling", "description": "Recipe ingredient scaling endpoints" }
  ],
  "paths": {
    "/api/scale": {
      "post": {
        "summary": "Scale recipe ingredient quantities",
        "description": "Takes a list of recipe ingredient lines and a from/to ratio (or an explicit ratio), returns the same lines with quantities scaled and units smart-promoted (3 tsp → 1 tbsp, 16 tbsp → 1 cup, 1000 g → 1 kg).\n\nLines without a parseable quantity pass through unchanged.\n\nProvide either `ratio`, or both `from` and `to`. If you provide both forms, `ratio` takes precedence.",
        "operationId": "scaleRecipe",
        "tags": ["Scaling"],
        "requestBody": {
          "required": true,
          "description": "Ingredient lines plus the scaling factor.",
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ScaleRequest" },
              "examples": {
                "fromTo": {
                  "summary": "Scale from 4 to 6 servings",
                  "value": {
                    "ingredients": [
                      "1 1/2 cups all-purpose flour",
                      "2 tsp salt",
                      "3 large eggs"
                    ],
                    "from": 4,
                    "to": 6
                  }
                },
                "ratio": {
                  "summary": "Halve a recipe explicitly",
                  "value": {
                    "ingredients": ["1 cup butter", "2 cups sugar"],
                    "ratio": 0.5
                  }
                },
                "localizedUnits": {
                  "summary": "Scale 1.5× and translate units to Spanish",
                  "value": {
                    "ingredients": ["2 tablespoons olive oil", "1 cup white rice"],
                    "ratio": 1.5,
                    "lang": "es"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful scaling",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ScaleSuccess" },
                "example": {
                  "ok": true,
                  "ratio": 1.5,
                  "scaled": [
                    "2 1/4 cups all-purpose flour",
                    "1 tbsp salt",
                    "4 1/2 large eggs"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ScaleError" }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ScaleError" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ScaleRequest": {
        "type": "object",
        "required": ["ingredients"],
        "properties": {
          "ingredients": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": { "type": "string", "maxLength": 500 },
            "description": "Recipe ingredient 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."
          },
          "from": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Original recipe servings. Provide with `to` to compute the ratio automatically."
          },
          "to": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Target recipe servings."
          },
          "ratio": {
            "type": "number",
            "minimum": 0.01,
            "maximum": 100,
            "description": "Explicit scaling factor (alternative to from+to). Takes precedence if both forms provided."
          },
          "lang": {
            "type": "string",
            "maxLength": 16,
            "description": "ISO language code for unit-name translation. Defaults to English."
          }
        }
      },
      "ScaleSuccess": {
        "type": "object",
        "required": ["ok", "ratio", "scaled"],
        "properties": {
          "ok": { "type": "boolean", "enum": [true] },
          "ratio": { "type": "number" },
          "scaled": { "type": "array", "items": { "type": "string" } }
        }
      },
      "ScaleError": {
        "type": "object",
        "required": ["ok", "error"],
        "properties": {
          "ok": { "type": "boolean", "enum": [false] },
          "error": { "type": "string" }
        }
      }
    }
  }
}
