BETTERMENU
Studio

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.

GET
/studio/recipes

Query Parameters

limit?|

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.

cursor?|

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.

sort_by?|

Field to sort by. Defaults to updated_at.

order?|

Sort direction. Defaults to desc (most recently updated first).

status?|

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": {}
    }
  ]
}
BETTERMENU

FDA-compliant nutrition labels from a recipe, in minutes.

Visit bettermenu.live