Merran documentation API & integrations
Stand-ins for an ingredient
const url = 'http://localhost:3000/api/recipes/lemon-chicken/stand-ins';const options = { method: 'POST', headers: { cookie: 'merran.session_token=<merran.session_token>', 'Content-Type': 'application/json' }, body: '{"ingredientId":"0199e8b0-5a10-7a01-8b00-000000000012"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:3000/api/recipes/lemon-chicken/stand-ins \ --header 'Content-Type: application/json' \ --cookie merran.session_token=<merran.session_token> \ --data '{ "ingredientId": "0199e8b0-5a10-7a01-8b00-000000000012" }'For an ingredient someone’s out of, or doesn’t eat: two to four stand-ins that work in this recipe, with amounts for the recipe as written, what’s in the pantry first, and nothing the household avoids or that’s against its diets. Each says how to use it, and rewrites any step it changes. Nothing is saved; use POST /recipes/{recipe}/swap to put one in the recipe. Uses the household’s model for swaps, and counts towards its AI spend. With an API key, it needs the recipes: write permission.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The recipe’s id, or its slug.
Example
lemon-chickenThe recipe’s id, or its slug.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Example
0199e8b0-5a10-7a01-8b00-000000000012Example
{ "ingredientId": "0199e8b0-5a10-7a01-8b00-000000000012"}Responses
Section titled “Responses”Stand-ins, best first; maybe none.
object
object
Ingredient lines in its place, with amounts for the recipe as written.
How to use it, and how it changes the dish.
It’s in the pantry.
Steps it changes, rewritten. Usually none.
object
The step, rewritten.
Example
{ "swaps": [ { "lines": [ "1 cup Greek yogurt" ], "note": "Stir in off the heat so it doesn't split; a little tangier.", "atHome": true, "steps": [] } ]}Not signed in.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}Not allowed.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}No such recipe, or no such ingredient in it.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}This month’s AI limit is reached, or the AI is busy.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}The AI provider failed.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}© 2026 Kyle Johnson. Documentation: CC BY 4.0. Merran: AGPL-3.0-or-later.