recipes_list
ReadList recipes you may access, newest first, by scope. `all` (the default) is your recipes and the ones shared with you. `mine` is yours. `sharedWithMe` is shared with you by their owner, read-only. `public` is readable by every user. Shared and public both include the recipes inside such a recipe that have the same owner: sharing or publishing a recipe shares what it is made of. `usable` is what the app offers when logging a meal or picking an ingredient: `all`, plus public recipes logged in your last 60 meals. `all`, `sharedWithMe` and `usable` leave out the recipes you hid with recipes_hide, and the ones that came with them only; `hidden` lists the ones you hid, and the first page of `all` and `sharedWithMe` says how many in `hiddenCount`. On a recipe of someone else, `hidden` says you hid it, `canHide` that you may (it is shared with you), and `canLeave` that it is shared with you by itself, so recipes_leave can remove it. canShare and canPublish are false for a recipe of yours that holds a copy of a privately shared recipe, or someone else's recipe that not everyone can read (recipes_get lists them in shareBlockers). canPublish is also false for a recipe imported from a social media post (publishRestricted; importedFrom names the site, instagram or tiktok), a copy of one, and a recipe that holds one; those can still be shared. `keptAt` is set on a copy made for you because you lost access to a recipe one of yours uses; `forkedFromId` names the original while it exists. `sharedWithCount` is how many people your own recipe is shared with (recipes_listShares names them); it is 0 for someone else's recipe. `ownerName` names whoever made a recipe shared with you; it is null for your own and for one you read only because it is public. Optional `search` keeps the recipes that match every word somewhere: the name, the description, an ingredient (a food or a recipe inside it), or the name of whoever shares the recipe with you (never the maker of a recipe that is only public). Results include capabilities and content revision; use nextCursor for pagination. imageUrl and imageThumbUrl are the photo at two sizes; for a photo added in the app they are temporary links (about a day), so fetch the recipe again for fresh ones.
Inputs: scope (all | mine | sharedWithMe | public | usable | hidden), limit (integer), cursor (string), search (string)
recipes_get
ReadRead a recipe you own, a public one, one shared with you, or one inside such a recipe, with its current ingredients, revision and capabilities. `lines` is every ingredient in the order to show them (those without a group first, then group by group): `kind` is `food` or `recipe`, `name` the food's or the recipe's, `quantity` and `unit` the amount. A `recipe` line is another recipe used as an ingredient, measured in its servings: `innerRecipe` has its id, name, photo and `servings` (how many servings its whole batch makes); read it with recipes_get, and its nutrition is in recipes_computeMacros. `ingredients` has the details of the food lines only (`ri` the line, `ing` the food). `groups` are the recipe's named groups of ingredients in order, empty for a recipe without groups; a line's `groupId` names its group, or is null. `sharedWithCount` is how many people your own recipe is shared with (0 for someone else's). `ownerName` names whoever made a recipe shared with you (null for your own, and for one you read only because it is public). `copiedFrom`, on your own copy, says where it came from: the recipe it was copied from, while that exists. `yours` is true when that was yours; `ownerName` names its maker only when you share recipes with each other one way or the other; `public` says it is public. It is null for a recipe that is not a copy. `shareBlockers` lists what keeps your recipe from being shared or published (a copy that must stay private, or someone else's recipe that not everyone can read), empty when nothing does; reason `imported` is a recipe imported from Instagram or TikTok, or a copy of one, which blocks publishing only. `importedFrom` names the site an imported recipe came from, null for the rest. `keptAt` is set on a copy made for you because you lost access to a recipe one of yours uses. On a recipe of someone else, `hidden` says you hid it (recipes_hide), `canHide` that you may, and `canLeave` that it is shared with you by itself (recipes_leave); `cameWith` names the recipes shared with you that it is inside when it is shared with you only as part of them. For your own recipe, `visibleThrough` lists your recipes that contain it and are public or shared: through them others read it, whatever its own visibility says. Shared originals follow owner updates; reading does not create a copy. imageUrl and imageThumbUrl are the photo at two sizes; for a photo added in the app they are temporary links (about a day), so fetch the recipe again for fresh ones.
Inputs: id (string, required)
recipes_create
WriteCreate your own recipe, private by default. Public recipes are readable by authenticated users. Only you can edit the original. Creating a recipe does not log consumption.
Inputs: name (string, required), description (string | null), instructions (string | null), imageUrl (string | null), videoUrl (string | null), servings (integer), visibility (private | public)
recipes_update
WriteEdit your recipe using its expectedRevision and at least one changed field. Owner edits update the shared original for future uses; logged meals and forks remain unchanged. Non-owners must first fork. Publishing a recipe publishes the recipes inside it too. Restricted private-source copies cannot be published, nor can a recipe that holds one: the refusal names them. Recipes imported from Instagram or TikTok and copies of them (publishRestricted, importedFrom) can't be published either, nor can a recipe that holds one, but they can be shared; don't recreate them as public recipes. Making a recipe private leaves it readable through your recipes that contain it and are public or shared: the result lists those in `visibleThrough`. Other people's recipes that use it, or one inside it, as an ingredient and can't read it any more keep a private copy of it as it was. `servings` is how many servings the whole batch makes, its amounts unchanged (to make the batch bigger or smaller, every amount with it, use recipes_scale): when other recipes use this one as an ingredient, their lines keep their number of servings, so their nutrition changes at once; the result then has `usedIn`, with how many recipes use it and yours among them by name. Tell the user. imageUrl takes a public https link, or null to remove the photo; either replaces a photo added in the app, which is deleted when no recipe uses it. The returned imageUrl and imageThumbUrl of a photo added in the app are temporary links (about a day).
Inputs: name (string), description (string | null), instructions (string | null), imageUrl (string | null), videoUrl (string | null), servings (integer), visibility (private | public), id (string, required), expectedRevision (integer, required)
recipes_scale
WriteMake the whole batch of your own recipe bigger or smaller, with expectedRevision and the number of `servings` it should make: every ingredient's quantity is multiplied by the new ÷ the current servings, in its own unit (a recipe used as an ingredient is measured in its servings and scales the same way), and the recipe's servings are set, together, with one new revision. One serving stays the same, so its nutrition doesn't change. To change how many servings the same batch makes instead, use recipes_update with `servings`. Quantities are rounded to the nearest 0.001 of their unit, as they are stored: doubling or tripling and scaling back gives the same amounts, other scales can be off by 0.001. Refused when the recipe already makes that many servings, and when an ingredient would come to less than 0.001 or more than 999999.999 of its unit: the refusal names it. Recipes that use this one as an ingredient keep their number of its servings, and one serving holds the same as before, so their nutrition doesn't change. Logged meals are snapshots and never change. Returns the new revision, `servings`, `previousServings` and every ingredient's new amount in `lines` (id, name, quantity, unit), in the recipe's order. To undo, scale back to previousServings. Non-owners must fork first.
Inputs: id (string, required), expectedRevision (integer, required), servings (integer, required)
recipes_delete
Sensitive writeDelete your recipe. Existing meal snapshots and independent copies survive. Only the owner can delete. Refused while one of your own recipes uses it as an ingredient: the refusal names those recipes and their lines; remove the lines with recipes_removeIngredient first. Other people's recipes that use it keep a private copy of it as it was.
Inputs: id (string, required)
recipes_share
Sensitive writeOwner-only: grant read/use access to an existing account, by exact `email` or by `userId`: exactly one of the two. `userId` must be one of your contacts (recipes_shareContacts): someone you share one of your recipes with now, or someone who shares one of theirs with you now. Anyone else is refused as an unknown email is, NOT_FOUND, so it tells nothing about other accounts. A share by userId reveals no email: recipes_listShares and recipes_shareContacts show someone's email only while one of your shares with them was made by typing it. Does not create a copy. The recipes inside the recipe are shared with it, and taken back with it, unless you also shared one of them directly. A recipe that holds a copy of a privately shared recipe can't be shared: the refusal names it. A new share sends the recipient a push notification on their phone that names you and the recipe; none is sent when the recipe was already shared with them, when they were notified about it in the last 24 hours, or when you shared another recipe with them in the last 10 minutes. Repeated sharing is idempotent. Restricted copies cannot be shared; recipients cannot edit the original or reshare private copies.
Inputs: recipeId (string, required), email (string), userId (string)
recipes_unshare
Sensitive writeOwner-only: revoke an explicit recipe share by recipient userId. Idempotent. The recipes inside the recipe are taken back with it, unless you shared one of them directly. A recipe of theirs that uses this one, or one inside it, as an ingredient keeps a private copy of it as it was. Existing private copies and logged meals survive. A public recipe remains readable until made private, and a recipe stays readable through your recipes that contain it and are public or shared with that person: the result lists those in `visibleThrough`, so don't say access ended while it isn't empty.
Inputs: recipeId (string, required), userId (string, required)
recipes_listShares
ReadOwner-only: list the people you shared this recipe with. Whoever reads it only through a recipe that contains it is not listed here, but with that recipe. `email` is null unless one of your shares with them now was made by typing their email (a share by userId reveals none, recipes_share): don't try to find it out. Recipients cannot see the share list. This is not a user directory.
Inputs: recipeId (string, required)
recipes_shareContacts
ReadThe people you can share a recipe with by userId (recipes_share), most recent first: your contacts. A contact is someone you share one of your recipes with now (`sharedByYou`), or someone who shares one of theirs with you now (`sharedWithYou`); never yourself, and nobody else, so this is not a user directory. A contact drops out once no recipe is shared either way. `email` is set only for someone you share with whose email you typed; it is null for someone who only shares with you and for someone you share with only by userId, so refer to them by name and share by userId; don't try to find out their email. With `recipeId` (your own recipe), the people it is already shared with are left out, as recipes_listShares lists them. `lastSharedAt` is the newest share between you, either way. At most `limit` people (default 20, up to 50).
Inputs: recipeId (string), limit (integer)
recipes_hide
WriteTake a recipe shared with you off your lists, keeping it: recipes_list leaves it out of scopes all, sharedWithMe and usable, with the recipes that came with it (inside it, same owner) unless they are shared with you another way too. You can still read, log and copy it, and your recipes that use it as an ingredient keep following its owner's changes. Its owner isn't told. Only for a recipe shared with you, by itself or inside a shared recipe; not your own, or one that is only public. Idempotent. Undo with recipes_unhide; recipes_list with scope hidden lists them. To stop reading it altogether, use recipes_leave.
Inputs: id (string, required)
recipes_unhide
WritePut a recipe you hid with recipes_hide back on your lists, with the recipes that came with it. Idempotent.
Inputs: id (string, required)
recipes_leave
Sensitive writeRemove a recipe someone shared with you: your share of it ends, as if its owner had taken it back, with the recipes that came with it unless they are shared with you another way too. A recipe of yours that uses it, or one inside it, as an ingredient keeps a private copy of it as it was; logged meals and your copies stay. Its owner isn't notified; their list of shares no longer has you, and they can share it again. Only for a recipe shared with you by itself (`canLeave`); one that came inside a shared recipe can be hidden, or removed with that recipe. It stays readable while it is public, and stays on your lists while `cameWith` in the result isn't empty: it is still shared with you as part of those recipes, so don't say it is gone. To keep it and only take it off your lists, use recipes_hide.
Inputs: id (string, required)
recipes_addGroup
WriteAdd a named group of ingredients (for example Dough, Sauce, Topping) to your own recipe, with expectedRevision. Groups are optional: a recipe without them is a flat list, and ingredients with and without a group can be mixed. The group is added last. A name is used once in a recipe, whatever the letter case. A recipe has at most 30 groups. Put ingredients in the group with recipes_addIngredient or recipes_updateIngredient. Returns the group and the new recipe revision. Non-owners must fork first.
Inputs: recipeId (string, required), name (string, required), expectedRevision (integer, required)
recipes_updateGroup
WriteRename a group of ingredients of your own recipe, move it, or both, with expectedRevision and at least one of `name` and `position`. `position` counts the recipe's groups from 0; one past the end means last. The group's ingredients stay in it. Returns the group and the new recipe revision; stale edits conflict.
Inputs: id (string, required), expectedRevision (integer, required), name (string), position (integer)
recipes_removeGroup
Sensitive writeRemove a group of ingredients from your own recipe with expectedRevision. Its ingredients stay in the recipe without a group, after the ingredients that had none, in the order they had. To remove an ingredient use recipes_removeIngredient. Returns the group's ID and the new recipe revision.
Inputs: id (string, required), expectedRevision (integer, required)
recipes_addIngredient
WriteAdd an ingredient to your own recipe, with expectedRevision: a food or a recipe, exactly one of `foodId` and `innerRecipeId`. A food is an active food you can find (shared, or your own; never someone else's private food), with quantity and a unit the food supports. A recipe (an inner recipe) is any recipe you can read, used as an ingredient: `quantity` is how many of its servings go in (0.5 for half a serving), and `unit` is `serving` or left out. It is used as it is now: when it changes, so does this recipe's nutrition. Should you lose access to someone else's recipe later (its owner takes the share back, makes it private or deletes it), your recipe keeps a private copy of it as it was, marked with `keptAt`. A recipe can't contain itself, directly or through another; recipes nest at most 5 levels, counting the recipes that use this one; a recipe holds at most 50 recipes inside it. Whoever reads a recipe must be able to read what is inside it: a copy of a privately shared recipe, or someone else's recipe that not everyone can read, can't go into a recipe that is public or shared, or that is inside one, and a recipe that holds one can't be shared or published. A recipe imported from Instagram or TikTok, or a copy of one, can't go into a recipe that is public or inside a public one. Optional groupId (from recipes_get or recipes_addGroup) puts the ingredient last in that group of this recipe; without one it goes last among the ingredients that have no group. A recipe has at most 200 ingredients. Returns the ingredient and new revision. Missing nutrients stay unknown. Non-owners must fork first.
Inputs: recipeId (string, required), foodId (string), innerRecipeId (string), expectedRevision (integer, required), quantity (number, required), unit (g | ml | oz | lb | cup | tbsp | tsp | piece | serving), notes (string | null), groupId (string | null)
recipes_updateIngredient
WriteEdit an ingredient of your own recipe with expectedRevision and at least one changed field. For a recipe used as an ingredient, `quantity` is its servings and the unit stays `serving`. `groupId` moves it to that group of the same recipe, and `groupId: null` takes it out of its group; leave groupId out to keep it where it is. `position` places it among the ingredients of its group (or among those without a group), counted from 0; one past the end means last. An ingredient that changes group without a position goes last. Existing archived foods remain usable. Returns the ingredient and new recipe revision; stale edits conflict.
Inputs: id (string, required), expectedRevision (integer, required), quantity (number), unit (g | ml | oz | lb | cup | tbsp | tsp | piece | serving), notes (string | null), groupId (string | null), position (integer)
recipes_replaceIngredient
WriteSwap the food of an ingredient of your own recipe for another food, with expectedRevision: the ingredient keeps its place, its group and its notes, and takes the new food at quantity and a unit the new food supports. The new food is an active food you can find (shared, or your own; never someone else's private food). Only a food's ingredient can be swapped: a recipe used as an ingredient is removed and the new one added (recipes_removeIngredient, recipes_addIngredient). Returns the ingredient and the new recipe revision; stale edits conflict. Non-owners must fork first.
Inputs: id (string, required), expectedRevision (integer, required), foodId (string, required), quantity (number, required), unit (g | ml | oz | lb | cup | tbsp | tsp | piece | serving, required)
recipes_removeIngredient
Sensitive writeRemove an ingredient from your own recipe with expectedRevision. Taking a recipe out of a shared or public recipe takes it back from whoever read it only through this one; their recipes that used it as an ingredient keep a private copy of it as it was. Returns its ID and the new recipe revision. Non-owners must fork first.
Inputs: id (string, required), expectedRevision (integer, required)
recipes_fork
WriteExplicitly customize or keep a separate copy of an accessible recipe. Pass expectedRevision; optional idempotencyKey prevents duplicate copies on retries. Copies start private with independent ingredients, the same groups of ingredients, and no shares. The recipes inside it are copied with it, each once, so everything in the copy is yours; a recipe inside it that is already yours is used as it is. The result is the copy of the recipe itself; recipes_get shows the copies inside it. A copy of a recipe you could read only through a private share must always remain private, even after revocation/source deletion, as must a copy of such a copy; this holds for each recipe copied. A copy of a recipe imported from Instagram or TikTok can be shared but never made public, like the original. Public-source copies may be shared. Foods are referenced, not copied.
Inputs: id (string, required), expectedRevision (integer, required), idempotencyKey (string)
recipes_computeMacros
ReadCompute current accessible recipe nutrition. Owner updates and shared-food corrections affect current totals, not historical meal snapshots. Carbs/fat/fiber are known sums with missing-food counts; report incompleteness. `breakdown` has one line for each ingredient, in the recipe's order, with `lineId`. A recipe used as an ingredient is one line (`kind: recipe`, `recipeId`, its name in `foodName`, `foodId` null): its amount is (that recipe's whole batch ÷ its servings) × the servings used, as that recipe is now; its carbs, fat and fiber are the sums of what the foods inside it list, and its missing counts say how many foods inside it don't; `empty` means it has no ingredients yet and counts nothing. Includes recipe revision, which changes with this recipe's own ingredients, not with the foods and recipes it uses.
Inputs: id (string, required)