RPRecipeParseGet notified

Quickstart

You can be up and running in under five minutes. All you need is an API key.

1. Get an API key

Get notified at launch — 100 parse credits per month, no credit card required. Your first API key is created automatically.

2. Parse some ingredients

bash
curl -X POST https://api.recipeparse.sahilsharma.xyz/api/v1/parse/ingredients \
  -H "Authorization: Bearer rp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ingredients_raw": [
      "2¼ cups plain flour",
      "1 tsp baking soda",
      "115g unsalted butter, melted"
    ]
  }'

3. Use the response

json
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "parsed_ingredients": [
    {
      "raw_text": "2¼ cups plain flour",
      "name": "flour",
      "quantity": 2.25,
      "unit": "cup",
      "preparation": null,
      "confidence": 0.97,
      "product_matches": []
    },
    {
      "raw_text": "1 tsp baking soda",
      "name": "baking_soda",
      "quantity": 1.0,
      "unit": "tsp",
      "preparation": null,
      "confidence": 0.99,
      "product_matches": []
    },
    {
      "raw_text": "115g unsalted butter, melted",
      "name": "butter",
      "quantity": 115.0,
      "unit": "g",
      "preparation": "melted",
      "confidence": 0.98,
      "product_matches": []
    }
  ],
  "warnings": [],
  "meta": {
    "duration_ms": 842,
    "cached": false,
    "model_used": "recipeparse-ai-v1"
  }
}

Authentication

All API endpoints (except /health) require a Bearer token in the Authorization header.

bash
Authorization: Bearer rp_live_xxxxxxxxxxxxxxxx

API keys are scoped to a tenant and carry that tenant's plan, rate limits, and credit balance. You can create and revoke keys from the dashboard or via the Keys API.

Credits & limits

Usage is metered in parse credits. Each plan includes a monthly credit allowance that resets on the 1st of each month.

PlanParse creditsEnrich creditsRate limit
Free100010 req/min
Starter2,0001,00060 req/min
Pro20,00010,000300 req/min
EnterpriseUnlimitedUnlimitedCustom

Credit costs: Full parse = 1 credit. Step annotation only = 0.5 credits. Product enrichment = 1 credit per retailer. Cache hits are free.

POST /api/v1/parse/recipe

POST/api/v1/parse/recipe1 parse credit

Full pipeline: parses ingredients, annotates method steps, and optionally enriches with product matches — all in one call.

json
// Request body
{
  "ingredients_raw": ["2¼ cups plain flour", "1 tsp baking soda"],
  "steps_raw": ["Mix the flour and baking soda together."],
  "options": {
    "enrich": false,          // set true to add product matches
    "retailers": ["tesco"]    // required if enrich: true
  }
}

POST /api/v1/parse/ingredients

POST/api/v1/parse/ingredients1 parse credit

Parse ingredient strings only. Returns structured ParsedIngredient objects with quantity, unit, canonical name, preparation, and confidence.

json
// Request body
{
  "ingredients_raw": [
    "2¼ cups plain flour",
    "115g unsalted butter, melted"
  ]
}

POST /api/v1/parse/steps

POST/api/v1/parse/steps0.5 parse credits

Annotates method steps against already-parsed ingredients. Returns character-level spans that link ingredient mentions in the method text back to the parsed ingredient objects. This endpoint does not cache.

json
// Request body
{
  "steps_raw": ["Mix the flour and baking soda together."],
  "parsed_ingredients": [
    { "name": "flour", "raw_text": "2¼ cups plain flour", ... },
    { "name": "baking_soda", "raw_text": "1 tsp baking soda", ... }
  ]
}

// Each annotated step includes spans:
// { "text": "flour", "start": 8, "end": 13,
//   "span_type": "ingredient", "ingredient_ref": "flour" }

POST /api/v1/catalogue/enrich

POST/api/v1/catalogue/enrich1 enrich credit / retailer

Enriches a list of parsed ingredients with product matches from the catalogue. Matching runs exact → brand-family → generic → fuzzy (RapidFuzz, threshold 82).

API keys

POST/api/v1/keysCreate a new API key
GET/api/v1/keysList all API keys for your tenant
DELETE/api/v1/keys/{id}Revoke an API key

Usage

GET/api/v1/usage/summaryMonthly usage totals (credits used/remaining)
GET/api/v1/usage/eventsPaginated log of individual usage events

Canonical IDs

Every parsed ingredient gets a name field containing its canonical snake_case ID — for example baking_soda for both "bicarbonate of soda" and "baking soda". IDs are produced by a 7-step deterministic pipeline: lowercase → strip punctuation → remove prep descriptors → remove articles → synonym map → spaces to underscores → collapse underscores.

Synonym rules are stored in the database and applied at parse time. If two ingredients in the same request resolve to the same canonical ID, the second is suffixed: butter + butter butter, butter_2. A warning is added to the response.

Confidence scoring

Each ParsedIngredient carries a confidence score between 0.0 and 1.0, starting at 1.0 and penalised 0.05 per validation flag (missing unit, ambiguous quantity, duplicate name, etc.). Ingredients with confidence below 0.70 are additionally flagged low_confidence: true.

Caching

Parse results are cached in Postgres for 30 days. The cache key is a SHA-256 hash of the sorted ingredient list plus any options. Two requests with the same ingredients in different order hit the same cache entry. Cache hits cost 0 credits and return immediately with meta.cached: true.

Step annotation results are not cached.

Error handling

StatusMeaning
400Validation error — check your request body
401Missing or invalid API key
422Unprocessable entity — malformed JSON
429Rate limit or monthly credit cap exceeded
200 + PARSE_ERROR warningLLM returned invalid JSON twice — partial result returned
500Internal server error

All error responses include a JSON body with a detail field describing what went wrong.