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
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
{
"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.
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.
| Plan | Parse credits | Enrich credits | Rate limit |
|---|---|---|---|
| Free | 100 | 0 | 10 req/min |
| Starter | 2,000 | 1,000 | 60 req/min |
| Pro | 20,000 | 10,000 | 300 req/min |
| Enterprise | Unlimited | Unlimited | Custom |
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
/api/v1/parse/recipe1 parse creditFull pipeline: parses ingredients, annotates method steps, and optionally enriches with product matches — all in one call.
// 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
/api/v1/parse/ingredients1 parse creditParse ingredient strings only. Returns structured ParsedIngredient objects with quantity, unit, canonical name, preparation, and confidence.
// Request body
{
"ingredients_raw": [
"2¼ cups plain flour",
"115g unsalted butter, melted"
]
}POST /api/v1/parse/steps
/api/v1/parse/steps0.5 parse creditsAnnotates 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.
// 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
/api/v1/catalogue/enrich1 enrich credit / retailerEnriches a list of parsed ingredients with product matches from the catalogue. Matching runs exact → brand-family → generic → fuzzy (RapidFuzz, threshold 82).
API keys
/api/v1/keys— Create a new API key/api/v1/keys— List all API keys for your tenant/api/v1/keys/{id}— Revoke an API keyUsage
/api/v1/usage/summary— Monthly usage totals (credits used/remaining)/api/v1/usage/events— Paginated log of individual usage eventsCanonical 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
| Status | Meaning |
|---|---|
| 400 | Validation error — check your request body |
| 401 | Missing or invalid API key |
| 422 | Unprocessable entity — malformed JSON |
| 429 | Rate limit or monthly credit cap exceeded |
| 200 + PARSE_ERROR warning | LLM returned invalid JSON twice — partial result returned |
| 500 | Internal server error |
All error responses include a JSON body with a detail field describing what went wrong.