Food Info Recipes API API

The RecipesApi API from Food Info — 2 operation(s) for recipesapi.

Documentation

Specifications

Other Resources

OpenAPI Specification

food-info-recipesapi-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Food Info Recipes API API
  description: 'Nutrition data for millions of foods, merged from five national food-composition datasets: USDA FoodData Central (US), McCance & Widdowson''s CoFID (UK), ANSES Ciqual (France), the Danish Food Composition Database, and FSANZ AUSNUT (Australia/NZ), plus Open Food Facts for branded products.


    Authenticate with an API key in the `X-Api-Key` header. A free account gets a key with 10 requests/minute and 100/day; the Practitioner plan raises that to 60/minute and 10,000/day. Quotas are counted per account, not per key. Every response carries `X-RateLimit-Limit-Minute`, `X-RateLimit-Limit-Day` and `X-RateLimit-Tier`.


    Server-to-server only: CORS is not enabled, so keys stay off the browser.'
  contact:
    name: Food Info
    url: https://food-info.org/developer
    email: info@food-info.org
  version: v1
servers:
- url: https://api.food-info.org
security:
- {}
tags:
- name: RecipesApi
paths:
  /api/v1/recipes/parse:
    post:
      tags:
      - RecipesApi
      summary: Parse raw ingredient lines into structured {quantity, unit, food, …}. No DB, no food match.
      operationId: parseRecipeIngredients
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecipeParseRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RecipeParseRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RecipeParseRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ParsedIngredient'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/v1/recipes/analyze:
    post:
      tags:
      - RecipesApi
      summary: Analyze a recipe → per-line resolution + per-serving/per-100 g nutrition + source attribution + review flags.
      operationId: analyzeRecipeNutrition
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecipeAnalysisRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RecipeAnalysisRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RecipeAnalysisRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecipeAnalysis'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
components:
  schemas:
    ProblemDetails:
      type: object
      properties:
        type:
          type:
          - string
          - 'null'
        title:
          type:
          - string
          - 'null'
        status:
          type:
          - integer
          - 'null'
          format: int32
        detail:
          type:
          - string
          - 'null'
        instance:
          type:
          - string
          - 'null'
      additionalProperties: {}
    ParsedIngredient:
      required:
      - raw
      type: object
      properties:
        raw:
          type:
          - string
          - 'null'
          description: The original line, verbatim.
        quantity:
          type:
          - number
          - 'null'
          description: Resolved amount (the midpoint for a range); null when the line states no quantity.
          format: double
        quantityIsApproximate:
          type: boolean
          description: True when the quantity is a range ("2-3"), a word ("a"), or otherwise inexact.
        unit:
          type:
          - string
          - 'null'
          description: Canonical unit token (e.g. "tbsp", "g", "clove"); null when there is no unit.
        unitKind:
          $ref: '#/components/schemas/UnitKind'
        parenGrams:
          type:
          - number
          - 'null'
          description: Authoritative gram weight lifted from a parenthetical ("(120 g)"); null if absent.
          format: double
        foodPhrase:
          type:
          - string
          - 'null'
          description: The food name text, cleaned of quantity/unit/parenthetical/leading "of".
        prep:
          type:
          - string
          - 'null'
          description: Preparation/qualifier after the first comma ("sifted", "finely chopped"); null if none.
        confidence:
          type: number
          description: Parse confidence in [0,1]. Calibrated later against the golden set.
          format: double
        needsReview:
          type: boolean
          description: True when the line should be flagged for human confirmation (and logged as a miss).
      additionalProperties: false
      description: 'The structured result of parsing one raw recipe ingredient line (recipe-engine P0 slice 2). Every

        field the later stages need to resolve a food + a gram weight, plus a confidence and a

        FoodInfo.App.Recipes.ParsedIngredient.NeedsReview flag. When the parser can''t confidently structure a line it still returns

        a best-effort result with `NeedsReview = true` — the caller logs it to the resolution-miss

        backlog and asks the blogger to confirm; there is no model fallback.'
    RecipeAnalysisRequest:
      type: object
      properties:
        lines:
          type:
          - array
          - 'null'
          items:
            type: string
        region:
          type:
          - string
          - 'null'
        servings:
          type: integer
          format: int32
      additionalProperties: false
      description: 'Analyze a recipe: raw ingredient lines + the blog''s home nation (region-weighting) + servings.'
    RecipeParseRequest:
      type: object
      properties:
        lines:
          type:
          - array
          - 'null'
          items:
            type: string
      additionalProperties: false
      description: Body for `POST /api/v1/recipes/parse`.
    RecipeNutrientRow:
      type: object
      properties:
        nutrientId:
          type: integer
          format: int32
        name:
          type:
          - string
          - 'null'
        unit:
          type:
          - string
          - 'null'
        perServing:
          type: number
          format: double
        per100g:
          type: number
          format: double
        percentDailyValue:
          type:
          - number
          - 'null'
          format: double
        referenceAmount:
          type:
          - number
          - 'null'
          format: double
      additionalProperties: false
      description: "One nutrient in the full breakdown: per-serving + per-100 g amounts in the nutrient's own unit,\n            plus the per-serving %DV + daily reference (drives the coloured bars, same as the food pages)."
    RecipeAnalysis:
      type: object
      properties:
        ingredients:
          type:
          - array
          - 'null'
          items:
            $ref: '#/components/schemas/IngredientResult'
        perServing:
          $ref: '#/components/schemas/NutritionFacts'
        per100g:
          $ref: '#/components/schemas/NutritionFacts'
        totalGrams:
          type: number
          format: double
        servings:
          type: integer
          format: int32
        sources:
          type:
          - array
          - 'null'
          items:
            type: string
        reviewFlags:
          type:
          - array
          - 'null'
          items:
            type: string
        nutrientGroups:
          type:
          - array
          - 'null'
          items:
            $ref: '#/components/schemas/RecipeNutrientGroup'
      additionalProperties: false
      description: "Full recipe analysis: per-line results, per-serving + per-100 g nutrition, the source DBs used\n            (for attribution — required on every page), and any lines flagged for human confirmation."
    RecipeNutrientGroup:
      type: object
      properties:
        category:
          type:
          - string
          - 'null'
        rows:
          type:
          - array
          - 'null'
          items:
            $ref: '#/components/schemas/RecipeNutrientRow'
      additionalProperties: false
      description: A category of nutrients (Proximates, Vitamins, Minerals…) for the full breakdown modal, ordered.
    NutritionFacts:
      type: object
      properties:
        energyKcal:
          type: number
          format: double
        proteinG:
          type: number
          format: double
        fatG:
          type: number
          format: double
        saturatedFatG:
          type: number
          format: double
        carbohydrateG:
          type: number
          format: double
        sugarsG:
          type: number
          format: double
        fibreG:
          type: number
          format: double
        sodiumMg:
          type: number
          format: double
      additionalProperties: false
      description: The WPRM-shaped nutrition label (per serving or per 100 g). Sodium in mg; the rest in g / kcal.
    UnitKind:
      enum:
      - None
      - Mass
      - Volume
      - Count
      - Vague
      type: string
      description: How a parsed unit converts to grams downstream (recipe-engine Stage 4, mass-resolve).
    IngredientResult:
      required:
      - raw
      type: object
      properties:
        raw:
          type:
          - string
          - 'null'
        foodPhrase:
          type:
          - string
          - 'null'
        foodId:
          type:
          - integer
          - 'null'
          format: int32
        matchedDescription:
          type:
          - string
          - 'null'
        source:
          type:
          - string
          - 'null'
          description: Attribution display name of the matched food's source DB (e.g. "The Danish Food Composition Database").
        grams:
          type:
          - number
          - 'null'
          format: double
        confidence:
          type: number
          format: double
        needsReview:
          type: boolean
        note:
          type:
          - string
          - 'null'
          description: Why it needs review / could not resolve, when applicable.
      additionalProperties: false
      description: 'The resolution of one ingredient line: what it parsed to, the food it matched, and the grams.'
  securitySchemes:
    ApiKey:
      type: apiKey
      description: Developer API key. Create one at https://food-info.org/developer
      name: X-Api-Key
      in: header