Merran documentation API & integrations
Tidy up a recipe
const url = 'http://localhost:3000/api/recipes/lemon-chicken/tidy';const options = { method: 'POST', headers: { cookie: 'merran.session_token=<merran.session_token>', 'Content-Type': 'application/json' }, body: '{"sections":["steps","tags","marks"]}'};
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/tidy \ --header 'Content-Type: application/json' \ --cookie merran.session_token=<merran.session_token> \ --data '{ "sections": [ "steps", "tags", "marks" ] }'AI tidies the recipe: consistent ingredient lines, short clear steps, tags from the household’s own, a description and servings and times when they’re missing, and marks on what it can do without. Nothing changes yet: the suggestion waits in the Review queue, in place of any earlier one for the recipe, and comes back here. Null when there’s nothing to change. Uses the household’s model for tidying, 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 Body
Section titled “Request Body”object
What to tidy; every section when left out.
Example
{ "sections": [ "steps", "tags", "marks" ]}Responses
Section titled “Responses”Its suggestion, or null.
object
object
object
What it changes, in a sentence.
The sections it changes, each applied or skipped on its own.
The cooking note it came from, for one made from a note.
What an assistant’s suggestion adds, by kind: recipe (a recipe, as the editor writes one), meals (meals for the plan), items (lines for the list), tastes to remember (avoid, diets, weeknightMinutes), a recipe page to import (url, name, site, photo, minutes, why), or a stand-in for an ingredient (ingredientId, insteadOf, lines, note, steps), which applying saves to the recipe. Null for changes to a recipe’s sections.
The assistant’s chat it came from, for one from the assistant.
A recipe’s sections, only the ones a suggestion changes. Ingredients and steps are editor lines.
object
object
object
object
The food Merran knows that the line is, as a food key; null when no one has said.
A recipe’s sections, only the ones a suggestion changes. Ingredients and steps are editor lines.
object
object
object
object
The food Merran knows that the line is, as a food key; null when no one has said.
Example
{ "proposal": { "id": "0199e8b0-5a10-7a01-8b00-000000000029", "kind": "tidy", "status": "pending", "resolvedAt": null, "recipe": { "id": "0199e8b0-5a10-7a01-8b00-000000000006", "slug": "lemon-chicken", "name": "Lemon Chicken" }, "summary": "Split a long step and marked the chicken as needed.", "sections": [ "steps", "marks" ], "note": null, "payload": null, "chat": null, "before": { "steps": [ "Rub the chicken with lemon and garlic, then roast it at 200°C for 40 minutes until golden. Enjoy!" ], "marks": [ { "line": "2 lb chicken thighs", "mark": null }, { "line": "2 lemons, juiced", "mark": null } ] }, "after": { "steps": [ "Rub the chicken with lemon and garlic.", "Roast at 200°C for 40 minutes, until golden." ], "marks": [ { "line": "2 lb chicken thighs", "mark": "needed" }, { "line": "2 lemons, juiced", "mark": "needed" } ] }, "createdAt": "2026-10-01T17:30:00.000Z" }}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.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}The model can’t do 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.