List Recipes
List recipes the caller can access in their organization.
Each list item carries latest_version_id — the HEAD ULID for
the recipe on the main branch — so callers can pin follow-up
reads or diff against a known commit without a per-row round-trip.
Each item also carries status — the recipe lifecycle state, here
always active or archived, never deleted: a deleted recipe
never appears in a list response (see below).
Pagination is cursor-based: omit cursor on the first page, then
pass meta.cursor from each response back as cursor on the next
call. The cursor is self-contained — it carries forward the
sort_by/order/status it was issued under, so subsequent pages
don't need to resend them. Passing a param that conflicts with what
the cursor was issued under starts a fresh query at page 1 under the
new param rather than erroring. A cursor that is not a cursor at all
also starts again at page 1. A cursor that still reads as one but
whose position is not in this list (for example, one edited or
retyped) is rejected with a 400 invalid_cursor: pass cursors back
exactly as returned. meta echoes the effective
sort_by/order/status actually applied. Server caps limit
at 100.
Sort defaults to updated_at desc (most recently updated first).
status filters to active or archived, and selects a pre-built
view partition rather than filtering rows after the read — so a
filtered page here fills to limit whenever more matches exist.
Deleted recipes are excluded from every page regardless of filter,
and deleted is not an accepted status value: a deleted recipe is
no longer readable. This is the opposite default to
listCustomIngredients, which includes deleted custom ingredients in
every page because those stay readable.
Available only on API versions declaring the recipe_versioning
capability. Requests without this capability receive a 404.
Query Parameters
Maximum number of recipes to return per page (1-100). Defaults to 10. Omit on later pages to keep the page size a cursor was issued under; passing a different value than the cursor was issued under restarts pagination at page 1 under the new size.
Opaque pagination cursor returned in meta.cursor from a previous response. Omit on the first page; pass back verbatim on each subsequent page. Self-contained — carries forward the sort/filter it was issued under, so subsequent pages don't need to resend sort_by/order/status.
Field to sort by. Defaults to updated_at.
Sort direction. Defaults to desc (most recently updated first).
Filter to recipes in this lifecycle state. Omit to return all non-deleted recipes.
Response Body
application/json
application/json
application/json
curl -X GET "https://api.bettermenu.live/studio/recipes"{
"data": [
{
"id": "string",
"name": "string",
"status": "active",
"country": "US",
"regulatory_authority": "US_FDA",
"demographic": "adults_and_children_over_4",
"created_at": "string",
"updated_at": "string",
"latest_version_id": "string"
}
],
"meta": {
"version": "string",
"request_id": "string",
"timestamp": "string",
"cursor": "string",
"has_more": true,
"sort_by": "updated_at",
"order": "asc",
"status": "active",
"prev_cursor": "string",
"next_cursor": "string",
"total": 0
}
}{
"type": "https://api.bettermenu.live/errors/recipe_not_found",
"title": "Recipe Not Found",
"status": 400,
"detail": "Recipe rcpe_abc123 does not exist",
"code": "recipe_not_found",
"retryable": true,
"instance": "/api/v1/recipes/rcpe_abc123",
"trace_id": "req_xyz789",
"errors": [
{}
],
"invalid_ids": [
"f_abc123",
"f_xyz789"
]
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}