Create your first menu
Step-by-step guide with curl examples to go from zero to a saved menu — find your org, fetch a price band, create the menu, and add a category and item.
Create your first menu
This guide walks you through standing up a brand new menu in Flipdish from scratch using nothing but curl. You'll authenticate, find your org, fetch a price band, create an empty menu, and add a category and item.
This guide stops at "menu saved." It does not cover making the menu live for customers — for that, follow Publish your first menu once you've finished here.
If you already have menus and just want to read, edit, or publish an existing one, see Use v3 menus as an integrator.
BetaThe Menu Management API is currently in beta and may change without notice. Pin your integration to specific revisions and be defensive about unknown fields in responses.
Working with an AI assistant?Each step below has a "💬 Ask an AI" block (collapsed by default — click the heading to expand) with a prompt you can paste into Claude, ChatGPT, Cursor, Copilot, or any other AI tool. Hover the code block to reveal the copy button. Every prompt uses placeholders like
<MY_CLIENT_ID>instead of real values, so it's safe to copy as-is. Substitute your real values after the AI returns the command, not before. Never paste secrets (client secret, access token) into a chat window.
How everything fits together
Two things matter for creating a menu:
| Concept | ID prefix | What it is |
|---|---|---|
| Org | org123 | The top-level tenant. Every Menu Management path is scoped to an orgId. |
| Menu | menuId (UUID) | A document of categories, items, and modifiers that lives at the org level. |
Menus are not attached to properties directly. A menu lives at the org level. Making it live at a particular property happens later, in the publish step, by linking a revision to one or more of that property's sales channels. That's covered in the publish guide; this guide just gets the menu document saved.
Prerequisites
- A Flipdish OAuth App with access to the Org Management and Menu Management APIs. Create one in the Flipdish portal under My OAuth Apps. See Getting Started for the full walkthrough.
- A working knowledge of the menu object. This guide uses a deliberately tiny example; for the full shape, see Menu Structure v3.0.
curlandjq(or any HTTP client and JSON parser).
All examples use:
- Base URL:
https://api.flipdish.co - Auth header:
Authorization: Bearer <access_token> - A
User-Agentheader — it's required on every request.
Set up your session
This guide builds up a chain of values — access token, orgId, priceBandId, menuId, revisionId — that you'll reuse in every later step. Re-typing them gets old fast, and Claude Code's Bash tool runs each call in a fresh shell so anything exported in one tool call is gone by the next. The pattern below makes the values stick.
Create a file called .flipdish.env in your working directory with this content:
# --- Set these once ---
export FLIPDISH_BASE_URL=https://api.flipdish.co
export FLIPDISH_USER_AGENT='my-integration/1.0'
export FLIPDISH_CLIENT_ID=<your_client_id>
export FLIPDISH_CLIENT_SECRET=<your_client_secret>
# --- Captured by the steps below; do not edit by hand ---<your_client_id> and <your_client_secret> are placeholders — you'll replace them with values from the Flipdish portal in the Fill in your credentials sub-section below.
Recommended flow
Do the credentials setup outside any AI chat, then come back to Claude Code (or stay in your terminal) for the rest of the guide. The steps below only need to source the file — your client_secret never has to cross the chat boundary.
The recommended sequence is:
- In a terminal outside Claude Code, create
.flipdish.envwith the heredoc below, fill in the real values from the Flipdish portal, and gitignore it. - In Claude Code or your terminal, run steps 1–5 of this guide. Each step starts with
source ./.flipdish.envand appends new captured values back to the file.
If you'd rather do everything in a terminal and skip Claude Code entirely, that works the same way — every snippet in this guide is plain curl + jq.
Create the file
In a terminal, paste this whole block in one go. The closing EOF must land flush-left with no leading whitespace — don't paste it indented (e.g. inside another quote block) and don't press Enter line-by-line:
cat > .flipdish.env <<'EOF'
# --- Set these once ---
export FLIPDISH_BASE_URL=https://api.flipdish.co
export FLIPDISH_USER_AGENT='my-integration/1.0'
export FLIPDISH_CLIENT_ID=<your_client_id>
export FLIPDISH_CLIENT_SECRET=<your_client_secret>
# --- Captured by the steps below; do not edit by hand ---
EOFIf your shell sits at a > continuation prompt after the paste, the heredoc didn't close — usually because the EOF line ended up indented. Press Ctrl-C to abort, then redo with no leading whitespace. Or skip the heredoc entirely: run cat > .flipdish.env, paste the body lines, and press Ctrl-D on a new line to close the redirect.
Or use your editor: paste the same content into a new file named .flipdish.env in your working directory and save.
Then gitignore it:
grep -qxF .flipdish.env .gitignore 2>/dev/null || echo .flipdish.env >> .gitignoreFill in your credentials
Open .flipdish.env in your terminal $EDITOR and replace <your_client_id> and <your_client_secret> with the values from the OAuth App you created in the Flipdish portal:
"${EDITOR:-nano}" .flipdish.envThat falls back to nano (save with Ctrl-O, then Enter, then Ctrl-X to exit). Swap for vim, vi, code, subl, etc. as you prefer. On macOS, open -t .flipdish.env opens your default text editor; on most Linux desktops, xdg-open .flipdish.env does the same.
The portal labels are different from the OAuth2 spec terms used in this guide:
| In the Flipdish portal (My OAuth Apps) | In .flipdish.env | OAuth2 spec name |
|---|---|---|
| OAuth App ID | FLIPDISH_CLIENT_ID | client_id |
| Secret Key | FLIPDISH_CLIENT_SECRET | client_secret |
Open your OAuth app in the portal, copy the OAuth App ID into FLIPDISH_CLIENT_ID, click the eye icon next to Secret Key to reveal it, and copy that into FLIPDISH_CLIENT_SECRET. (The "Owner User ID" shown alongside is informational — you don't need it for this guide.)
Don't put yourclient_secretin any AI chatAnything you type into Claude Code's prompt (or any AI assistant) is sent to the model provider's API and stored on disk in your local conversation transcript. From there it can leak via screenshots,
/resumed sessions, transcript exports, hooks, MCP servers, or subagents. Editing.flipdish.envin a terminal editor keeps the secret on your machine only.If
.flipdish.envever leaks (or you suspect it has), rotate the Secret Key in the Flipdish portal under your OAuth App.
Use it from every step
Source it at the top of every shell command in this guide:
source ./.flipdish.envAs each step captures a new value (TOKEN, ORG_ID, PRICE_BAND_ID, MENU_ID, REVISION_ID), the example shows how to append it back into .flipdish.env. Repeated export lines in a sourced file are fine — the last one wins on the next source, so re-running a step (e.g. to refresh the token) just works.
Why this matters in Claude CodeEach
Bashinvocation in Claude Code is a fresh shell —export FOO=barin one tool call is not visible to the next. Sourcing.flipdish.envat the top of every command and appending captured values back to the file is what makes variables persist across tool calls so neither you nor your AI assistant has to re-paste them.When you ask an AI for help, include this rule in the prompt: "Always start commands with
source ./.flipdish.env, and after capturing any new value, append it back viaecho \"export VAR='$value'\" >> .flipdish.env."
If you keep.flipdish.envopen while running steps, reload itEach step below appends new
export ...lines to.flipdish.envas it captures values. If you've got the file open somewhere, that view is a snapshot from when you opened it — it won't refresh on its own.
- Terminal editor — reload from disk.
vim::e!.nano:Ctrl-Xto quit (answer N to discard the stale buffer), then re-open withnano .flipdish.env. GUI editors (VS Code, Cursor, etc.): close the tab and reopen, or run "Revert File" from the command palette.- Claude Code — every
Readtool call hits disk fresh, so just ask Claude to re-read the file. File contents Claude saw earlier in the conversation are a snapshot from that priorRead, not a live view; treat them as stale once a step has run.To check from any shell whether a value landed, without exposing the value itself:
grep -c '^export TOKEN=' .flipdish.env # count of TOKEN lines (>= 1 means it's there) tail -1 .flipdish.env | cut -c1-15 # first 15 chars of the last line
One-time scaffold via Claude Code (only if you haven't created the file yet)
If you're already inside Claude Code with no .flipdish.env on disk and no terminal handy, you can ask Claude to scaffold an empty template — then fill in the real values yourself in your editor.
One-time only — do not re-run this promptThe prompt below tells Claude to write
.flipdish.envfrom scratch with placeholder credentials. If.flipdish.envalready exists with real values, this would overwrite them. Claude Code will normally refuse to clobber a file with real-looking secrets, but don't rely on that — only run this prompt when the file doesn't exist yet, and never as a "reset" later.
💬 Scaffold .flipdish.env with placeholders — click to expand. Safe to copy: no secrets in this prompt. Hover the code block to copy.
Create a file called `.flipdish.env` in my current working directory
with exactly this content. Write the file directly using your
file-write tool — do NOT paste it back into chat, do NOT run it
through a shell heredoc, and do NOT ask me for any of the placeholder
values. If `.flipdish.env` already exists, STOP and tell me — do not
overwrite it.
# --- Set these once ---
export FLIPDISH_BASE_URL=https://api.flipdish.co
export FLIPDISH_USER_AGENT='my-integration/1.0'
export FLIPDISH_CLIENT_ID=<your_client_id>
export FLIPDISH_CLIENT_SECRET=<your_client_secret>
# --- Captured by the steps below; do not edit by hand ---
Then ensure `.flipdish.env` is listed in .gitignore (create .gitignore
if it doesn't exist; only append the line if it isn't already present).
Leave `<your_client_id>` and `<your_client_secret>` as literal
placeholders. I will fill in the real values myself in my editor — do
not ask me to paste them into the chat.After Claude writes the file, follow the Fill in your credentials section above to substitute the real values in your editor.
Step 1 — Get an access token
Exchange your client credentials for a bearer token, capture the access_token into $TOKEN, and persist it back to .flipdish.env so subsequent steps (and future Claude Code Bash calls) pick it up automatically.
source ./.flipdish.env
TOKEN=$(curl --silent --request POST \
--url "$FLIPDISH_BASE_URL/identity/connect/token" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data "client_id=$FLIPDISH_CLIENT_ID" \
--data "client_secret=$FLIPDISH_CLIENT_SECRET" \
--data scope=api \
| jq -r .access_token)
echo "export TOKEN='$TOKEN'" >> .flipdish.envTokens expire — re-run this step to refresh. The new export TOKEN= line appended at the bottom of .flipdish.env will override the old one on the next source.
💬 Ask an AI to fetch and persist a token — click to expand. Safe to copy: no secrets in the prompt. Hover the code block to copy.
I have a `.flipdish.env` file in my cwd that already exports
FLIPDISH_BASE_URL, FLIPDISH_USER_AGENT, FLIPDISH_CLIENT_ID, and
FLIPDISH_CLIENT_SECRET (the last two are placeholders <your_client_id>
and <your_client_secret> until I fill them in — do not ask me to paste
them into chat).
Show me a bash snippet that:
1. Sources ./.flipdish.env.
2. Exchanges the client credentials for an access token via curl
against $FLIPDISH_BASE_URL/identity/connect/token
(Content-Type: application/x-www-form-urlencoded;
grant_type=client_credentials, client_id=$FLIPDISH_CLIENT_ID,
client_secret=$FLIPDISH_CLIENT_SECRET, scope=api).
3. Extracts .access_token with jq into a shell variable named TOKEN.
4. Appends `export TOKEN='$TOKEN'` to .flipdish.env so it persists.
Don't inline my real credentials anywhere. Reference them only via the
$FLIPDISH_CLIENT_ID and $FLIPDISH_CLIENT_SECRET shell variables.Step 2 — Find your orgId
Every Menu Management and Org Management path is scoped by orgId. List the orgs your client has access to so you can pick one. Two paths — pick whichever fits your setup:
In a terminal, run this and read the table that comes back:
source ./.flipdish.env
curl --silent --request GET \
--url "$FLIPDISH_BASE_URL/orgManagement/orgs" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
| jq -r '.data[] | "\(.orgId)\t\(.name)\t\(.countryCode)"'You'll see one row per org as orgId<TAB>name<TAB>countryCode. Pick the id (shape: org123) of the org you want.
In Claude Code, paste the prompt below into chat. Claude will run the call via its Bash tool and print the table directly — no copy/paste or jq install required:
💬 Ask Claude to list my orgs and let me pick — click to expand. Safe to copy: no secrets in the prompt. Hover the code block to copy.
I have a .flipdish.env file in my cwd that already exports
FLIPDISH_BASE_URL, FLIPDISH_USER_AGENT, and TOKEN. Don't ask me for any
of those.
Run this and print the output to me as a readable table:
source ./.flipdish.env
curl --silent --request GET \
--url "$FLIPDISH_BASE_URL/orgManagement/orgs" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
| jq -r '.data[] | "\(.orgId)\t\(.name)\t\(.countryCode)"'
Then wait for me to tell you which orgId I want. After I pick, USE YOUR
BASH TOOL to run this exact command yourself — do NOT print the command
for me to run, ACTUALLY execute it:
echo "export ORG_ID='<my-pick>'" >> ./.flipdish.env
Then verify by running:
grep -c '^export ORG_ID=' .flipdish.env
and confirm the count is 1 or higher. Only after that's confirmed,
tell me we're ready for the next step.After picking, persist your choice (skip this if you used the Claude Code prompt — it does the append for you):
echo "export ORG_ID=org123" >> .flipdish.env
First time usingjq?The Flipdish API returns single-line JSON, which is hard to scan with dozens of records. The pipe to
jqabove flattens the response to one org per line. Install it withbrew install jq(macOS) orapt install jq(Debian/Ubuntu). The same trick works for every step below. (Claude Code's environment already hasjqavailable.)
Reference: get all orgs.
Step 3 — Get the org's price bands
Every item on a menu needs a PricingProfile tied to a priceBandId. Price bands are defined at the org level — list them so you can pick one.
In a terminal:
source ./.flipdish.env
curl --silent --request GET \
--url "$FLIPDISH_BASE_URL/orgManagement/orgs/$ORG_ID/priceBands" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
| jq -r '.data[] | "\(.id)\t\(.name // .displayName // "")"'You'll see one row per band as id<TAB>name. Pick the UUID of the band you want to price against.
In Claude Code, ask Claude to list and let you pick:
💬 Ask Claude to list my price bands and let me pick — click to expand. Safe to copy: no secrets in the prompt. Hover the code block to copy.
I have a .flipdish.env file in my cwd that already exports
FLIPDISH_BASE_URL, FLIPDISH_USER_AGENT, TOKEN, and ORG_ID. Don't ask me
for any of those.
Run this and print the output to me as a readable table:
source ./.flipdish.env
curl --silent --request GET \
--url "$FLIPDISH_BASE_URL/orgManagement/orgs/$ORG_ID/priceBands" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
| jq -r '.data[] | "\(.id)\t\(.name // .displayName // "")"'
Then wait for me to tell you which priceBandId I want. After I pick,
USE YOUR BASH TOOL to run this exact command yourself — do NOT print
the command for me to run, ACTUALLY execute it:
echo "export PRICE_BAND_ID='<my-pick>'" >> ./.flipdish.env
Then verify by running:
grep -c '^export PRICE_BAND_ID=' .flipdish.env
and confirm the count is 1 or higher. Only after that's confirmed,
tell me we're ready for the next step.After picking, persist the chosen UUID (skip this if Claude already appended it):
echo "export PRICE_BAND_ID=<chosen-priceband-uuid>" >> .flipdish.envYou'll plug $PRICE_BAND_ID into pricingProfiles[].priceBandId on every item in the next step.
Step 4 — Create the menu with a category and an item
Create the menu in a single POST, including at least one category and one item. The body must include categories, modifiers, and categoryGroups (the last two can be empty arrays). Valid type values are Store, Primary, Reward, and Kiosk.
Don't sendidfields when creatingOn create there are no IDs to send — the server generates a UUID for the menu and for every category and item, and returns them in the response. Capture those IDs. You'll send each one back unchanged on every future update so the entity keeps its identity (see step 5). Optionally you can also set
externalId(a free-form string) on a category or item to correlate it with your own system's identifier, but it's not required and isn't what Flipdish uses to track the entity — the server-generatedidis.
Write the request body to a file (the heredoc is unquoted, so $PRICE_BAND_ID is interpolated by the shell), then POST it. Capture MENU_ID and REVISION_ID from the response and append them to .flipdish.env.
source ./.flipdish.env
cat > new-menu.json <<JSON
{
"name": "Main Menu",
"type": "Store",
"description": "Our first menu",
"categories": [
{
"caption": "Burgers",
"enabled": true,
"availabilityOverrides": [],
"items": [
{
"caption": "Classic Burger",
"enabled": true,
"alcohol": false,
"allergens": ["Gluten", "Milk"],
"disableVouchers": false,
"excludeFromVoucherDiscounting": false,
"modifierMembers": [],
"charges": [],
"pricingProfiles": [
{
"priceBandId": "$PRICE_BAND_ID",
"collectionPrice": 9.99,
"collectionTax": 0,
"collectionTaxable": false,
"deliveryPrice": 9.99,
"deliveryTax": 0,
"deliveryTaxable": false,
"dineInPrice": 9.99,
"dineInTax": 0,
"dineInTaxable": false,
"takeawayPrice": 9.99,
"takeawayTax": 0,
"takeawayTaxable": false
}
]
}
]
}
],
"modifiers": [],
"categoryGroups": []
}
JSON
RESPONSE=$(curl --silent --request POST \
--url "$FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/menus" \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
--data @new-menu.json)
MENU_ID=$(echo "$RESPONSE" | jq -r .data.id)
REVISION_ID=$(echo "$RESPONSE" | jq -r .data.revisionId)
echo "export MENU_ID='$MENU_ID'" >> .flipdish.env
echo "export REVISION_ID='$REVISION_ID'" >> .flipdish.env
The response is wrapped in adataenvelopeMenu Management responses (create, update, get current) put the menu payload under a top-level
datakey — e.g.{"data": {"id": "...", "revisionId": 1, ...}}. The jq paths above use.data.idand.data.revisionIdaccordingly;.idat the top level returnsnull. The same pattern applies toPUTandGET .../currentresponses below.
The response contains the new menu, including:
data.id— captured into$MENU_ID.data.revisionId— captured into$REVISION_ID. Bumped when a draft is created. In v3 menus this revision behaviour is different from v2; see Use v3 menus as an integrator.- Server-generated
idUUIDs on the category and the item (insidedata.categories[].items[]). Keep these — you send them back unchanged on every update so the entities keep their identity (see step 5).
Guidelines for the create body
- Don't send
idon anything in the create body — there's nothing to send yet. The server generates the IDs and returns them; from then on you reuse them. - Every item needs a
pricingProfilesentry for every price band you intend to use, with all four dispatch-type prices filled in (collectionPrice,deliveryPrice,dineInPrice,takeawayPrice). - Use
availabilityOverridesrules (not duplicated items) to model "lunch only" or "Deliveroo only" behaviour.
Reference: create menu, Menu Structure v3.0.
💬 Ask an AI to create the menu and persist menuId / revisionId — click to expand. Safe to copy: no secrets in the prompt. Hover the code block to copy.
I have a `.flipdish.env` file that exports FLIPDISH_BASE_URL,
FLIPDISH_USER_AGENT, TOKEN, ORG_ID, and PRICE_BAND_ID. Don't ask me for
any of those.
Show me a bash snippet that:
1. Sources ./.flipdish.env.
2. Writes new-menu.json with name "Main Menu", type "Store", empty
modifiers and categoryGroups, and one category caption "Burgers"
containing one item caption "Classic Burger" priced at 9.99 across
collection/delivery/dine-in/takeaway with tax 0, priceBandId
interpolated from $PRICE_BAND_ID. Use a heredoc whose delimiter is
unquoted so $PRICE_BAND_ID expands.
3. POSTs the file to
$FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/menus
with Authorization: Bearer $TOKEN, Content-Type: application/json,
and User-Agent: $FLIPDISH_USER_AGENT.
4. Extracts .data.id and .data.revisionId from the response with jq
into MENU_ID and REVISION_ID. The response is wrapped in a `data`
envelope — `.id` and `.revisionId` at the top level are null.
5. Appends `export MENU_ID='$MENU_ID'` and
`export REVISION_ID='$REVISION_ID'` to .flipdish.env so they
persist across Claude Code Bash calls.
Important: on create there are no "id" fields to include — the server
generates them and returns them. Capture the returned menuId plus the
id of the category and item, because later updates must send those same
ids back so the entities keep their identity.Step 5 — Update the menu
The Menu Management API is coarse-grained: there are no per-category or per-item endpoints. To change anything you fetch the current menu, mutate the document, and PUT it back.
First, fetch the current menu:
source ./.flipdish.env
curl --silent --request GET \
--url "$FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/menus/$MENU_ID/current" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
> menu.json
Existing items keep theiridacross updates — send it backWhen you
PUTa menu, send each existing category and item back with theidthe server gave you — i.e. round-trip the IDs that came in theGET .../currentresponse. Existing entities keep their identity across the update; anidonly changes if you drop it. Add a new item or category by leaving itsidoff — the server mints one and returns it, and you reuse that on subsequent updates.
externalIdis an optional free-form string you can set to correlate an entity with your own system, but it isn't required and isn't the identity Flipdish tracks — the server-generatedidis. (Earlier guidance said to stripids and rely onexternalId; that was for a one-off migration and no longer applies — don't strip IDs.)
The robust pattern is: take the document you just fetched, mutate it in place, and PUT the whole thing back with every existing id intact. New entities go in without an id. The example below uses jq to unwrap the data envelope from menu.json, raise the price of the existing "Classic Burger", and append a brand-new "Cheeseburger" (no id) — leaving every existing id untouched:
source ./.flipdish.env
# Mutate the fetched menu.json (it still holds the `data` envelope from the GET above):
# - unwrap `.data`
# - raise "Classic Burger" to 10.99 across all dispatch types
# - append a new "Cheeseburger" with NO id (the server generates one)
jq --arg pb "$PRICE_BAND_ID" '
.data
| ( .categories[].items[] | select(.caption == "Classic Burger") | .pricingProfiles[] )
|= ( .collectionPrice = 10.99 | .deliveryPrice = 10.99 | .dineInPrice = 10.99 | .takeawayPrice = 10.99 )
| ( .categories[] | select(.caption == "Burgers") | .items ) += [
{
"caption": "Cheeseburger",
"enabled": true,
"alcohol": false,
"allergens": ["Gluten", "Milk"],
"disableVouchers": false,
"excludeFromVoucherDiscounting": false,
"modifierMembers": [],
"charges": [],
"pricingProfiles": [
{
"priceBandId": $pb,
"collectionPrice": 11.99, "collectionTax": 0, "collectionTaxable": false,
"deliveryPrice": 11.99, "deliveryTax": 0, "deliveryTaxable": false,
"dineInPrice": 11.99, "dineInTax": 0, "dineInTaxable": false,
"takeawayPrice": 11.99, "takeawayTax": 0, "takeawayTaxable": false
}
]
}
]
' menu.json > updated-menu.json
RESPONSE=$(curl --silent --request PUT \
--url "$FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/menus/$MENU_ID" \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--header "User-Agent: $FLIPDISH_USER_AGENT" \
--data @updated-menu.json)
REVISION_ID=$(echo "$RESPONSE" | jq -r .data.revisionId)
echo "export REVISION_ID='$REVISION_ID'" >> .flipdish.envThe PUT response is wrapped in the same data envelope as POST, hence .data.revisionId. The existing category and "Classic Burger" come back with the same ids they had before; only the newly added "Cheeseburger" gets a fresh server-generated id — capture it from the response if you'll reference that item later. The new REVISION_ID is what you'll publish in the next guide.
Guidelines when editing
- Round-trip the document you fetched from
.../currentand send every existing category and item back with itsidintact. Omitidonly on genuinely new entities — the server generates one and returns it. - Every item needs a
pricingProfilesentry for every price band the property uses, with all four dispatch-type prices filled in. - Use
availabilityOverridesrules (not duplicated items) to model "lunch only" or "Deliveroo only" behaviour.
Reference: get current menu, update menu, Menu Structure v3.0.
💬 Ask an AI to update the menu and persist the new revisionId — click to expand. Safe to copy: no secrets in the prompt. Hover the code block to copy.
I have a `.flipdish.env` file that exports FLIPDISH_BASE_URL,
FLIPDISH_USER_AGENT, TOKEN, ORG_ID, PRICE_BAND_ID, MENU_ID, and
REVISION_ID. Don't ask me for any of those.
I want to update my Flipdish menu by raising the price of the existing
item with caption "Classic Burger" to 10.99 and adding a new item with
caption "Cheeseburger" at 11.99, both inside the existing category with
caption "Burgers". All prices apply across collection, delivery,
dine-in, and takeaway, tax 0, using priceBandId $PRICE_BAND_ID.
Show me a bash snippet that:
1. Sources ./.flipdish.env.
2. GETs $FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/menus/$MENU_ID/current
with Authorization: Bearer $TOKEN and User-Agent: $FLIPDISH_USER_AGENT,
saving to menu.json.
3. Uses jq to produce updated-menu.json by:
- unwrapping the `data` envelope on the GET response (the menu
document lives at `.data`, not the top level),
- KEEPING every existing "id" on categories and items intact,
- raising the existing item's pricing,
- appending the new "Cheeseburger" item with NO "id" (the server
generates one),
without stripping or inventing any UUIDs.
4. PUTs $FLIPDISH_BASE_URL/menuManagement/orgs/$ORG_ID/menus/$MENU_ID
with --data @updated-menu.json.
5. Captures the new .data.revisionId into REVISION_ID (the PUT
response is also wrapped in a `data` envelope) and appends
`export REVISION_ID='$REVISION_ID'` to .flipdish.env so subsequent
Claude Code Bash calls and the publish guide pick it up.Where to go next
- Publish your first menu — pick sales channels, run a publish check, and make this menu live for customers.
- Use v3 menus as an integrator — the full editing, revisioning, exporting, and snoozing lifecycle.
- Menu Structure v3.0 — the complete menu document shape, including modifiers, category groups, and availability overrides.
- Error Handling — structured error responses the API returns.
- User Agents — the required
User-Agentheader format.
