UCP Checker
Guides · Food

UCP Food Checkout Explained: An Agent Orders Dinner, Step by Step

· 11 November 2026 · 14 min read

UCP now has a checkout for ordering food. On 10 November the spec merged PR #897, Food Checkout: an agent orders from one restaurant at a time, builds each dish with its choices and a note for the kitchen, picks delivery or pickup, adds a tip, and gets back an order number and a tracking link. It's the first capability from the Food Tech Council, and the first time UCP has a vertical of its own beyond shopping and lodging.

The change is on the spec's main branch and planned for the 2026-12-08 release, a plan that can move. We built it into a test restaurant and followed it through an agent run, from the menu to the order. Every request, reply and screenshot below is from that session, and the run is linked.

What is UCP Food Checkout?

UCP Food Checkout is a checkout capability for prepared food, dev.ucp.food.checkout, with two extensions: dev.ucp.food.fulfillment for delivery or pickup, and dev.ucp.food.tip for gratuity. In the spec's words:

The Checkout capability allows Platforms to facilitate checkout sessions for prepared food and beverage orders — from restaurants, cafes, bakeries, food trucks, etc.

It sits in its own service, dev.ucp.food, next to dev.ucp.shopping. It keeps shopping checkout's lifecycle (the same six statuses, the same five operations, the same totals, messages and payment handlers) and changes what a line is. The restaurant stays the merchant of record and keeps its menu, its prices and its kitchen.

Jing Li (Google) wrote it, and Ilya Grigorik (Shopify) and Amit Handa approved it. The Food Tech Council's inaugural members are Block (Square), DoorDash, Google, Toast and Uber Eats.

How it differs from shopping checkout

Shopping checkout Food checkout
A line is an item (a product or variant) and a quantity a dish, its modifications (each with a quantity per dish) and a note for the kitchen
Who you buy from the business one food_establishment per session
Fulfillment shipping or pickup to destinations delivery or pickup, as soon as possible or a requested_fulfillment_time, with handoff preferences and courier notes
Tips not defined dev.ucp.food.tip: options from the restaurant, a tip line in totals
After completion an order you can fetch with the order capability an order confirmation with a label and a tracking_url
Notices policies and disclosures food-safety disclosures: allergens, consumer_advisory, nutritional_info

The rules an agent has to follow

  • One kitchen per order. A session is bound to one establishment, and every dish must come from its live menu.
  • Ids, not descriptions. The agent sends a dish's id and its modifications' ids, plus quantities and the note. Titles and prices come back from the restaurant, which re-prices on every update.
  • Quantity per dish, never by repetition. "Platforms MUST NOT convey quantity by repetition": two eggs is one modification with quantity: 2. Two of the same dish built differently are two lines.
  • A note is only a note. The kitchen note "MUST NOT alter price or structured modifications". When a note asks for something the menu sells as a modification, the restaurant should warn with note_contains_modification, and the agent must never present the note as an applied change.
  • Show the final total. Delivery fees and tips can change up to the end, so the agent "MUST present the final totals[] for buyer confirmation before submitting payment."
  • Show the food-safety notices. Allergen and consumer-advisory disclosures go beside the dish they concern, and aren't dismissed automatically.
  • Give the buyer the tracking link. A completed order carries tracking_url, and the agent passes it on.

The setup

The restaurant is Kettle Street Noodles on food.ucpsandbox.com, one of our UCP Sandbox test stores: a takeout noodle bar with ramen and rice bowls that have required choices and add-ons, test cards only, and nothing cooked.

It offers both checkouts. Shopping checkout stays where it was, on /mcp and /ucp, for any agent. Food checkout has endpoints of its own, because its tools have the same names as the shopping ones:

"services": {
  "dev.ucp.shopping": [
    { "transport": "mcp",  "endpoint": "https://food.ucpsandbox.com/mcp" },
    { "transport": "rest", "endpoint": "https://food.ucpsandbox.com/ucp" }
  ],
  "dev.ucp.food": [
    { "transport": "mcp",  "endpoint": "https://food.ucpsandbox.com/food/mcp" },
    { "transport": "rest", "endpoint": "https://food.ucpsandbox.com/ucp/food" }
  ]
}

Food checkout is only active for an agent whose profile declares dev.ucp.food.checkout, the same capability intersection every UCP capability goes through. UCP Playground declares it, and connects to the food endpoints when a store offers them. The run used Gemini 3.6 Flash over MCP.

Step 1: the agent reads the menu

Finding a restaurant and reading its menu are outside the spec: dish and modification ids "come from upper-funnel menu discovery". So the test restaurant offers its own get_menu tool, clearly labelled as not part of UCP. It lists each dish with its choice groups:

{
  "id": "ramen_tonkotsu",
  "title": "Tonkotsu Ramen",
  "price": { "amount": 1600, "currency": "USD" },
  "allergens": ["gluten", "egg", "soy", "sesame"],
  "modifier_groups": [
    { "id": "noodles", "title": "Noodles", "min_selections": 1, "max_selections": 1,
      "modifications": [{ "id": "noodles_thin", "title": "Thin" }, { "id": "noodles_thick", "title": "Thick" }] },
    { "id": "spice", "title": "Spice", "min_selections": 1, "max_selections": 1, "modifications": ["…"] },
    { "id": "addons", "title": "Add-ons", "min_selections": 0,
      "modifications": [{ "id": "addon_ajitama", "title": "Ajitama Egg", "price": { "amount": 200, "currency": "USD" }, "max_quantity": 3 }, "…"] }
  ]
}

Playground's Inspect shows the same menu as a buyer would see it, and builds an order by hand: one choice from each required group, add-ons with a quantity, and a note.

Inspect at food.ucpsandbox.com in Store mode: Tonkotsu Ramen, US$16.00, with "Noodles · choose one" (Thick selected), "Spice · choose one" (Hot selected), add-ons with prices (one Ajitama Egg at +US$2.00), a kitchen note "No scallion" and a quantity of 2.

Step 2: the agent builds the order

The buyer asked for two Tonkotsu Ramen with thick noodles, hot, and an extra egg each, and a large Karaage bowl with white rice and the sauce on the side, delivered, with a 15% tip. The agent turned the order into one create_checkout:

{
  "food_establishment": { "id": "loc_division" },
  "line_items": [
    { "dish": { "id": "ramen_tonkotsu" }, "quantity": 2,
      "modifications": [{ "id": "noodles_thick" }, { "id": "spice_hot" }, { "id": "addon_ajitama" }] },
    { "dish": { "id": "bowl_karaage" }, "quantity": 1,
      "modifications": [{ "id": "rice_white" }, { "id": "size_large" }],
      "note": "sauce on the side" }
  ],
  "fulfillment": { "methods": [{ "type": "delivery",
    "destination": { "type": "delivery_address", "address": { "…": "12 SE Ash St, Portland, OR 97214" } } }] }
}

"Sauce on the side" went in the note, which is where it belongs: the menu has no modification for it. The tip isn't there yet. The tip extension has the agent choose a suggested tip on update, once the restaurant has returned its options (selected_option_id is omitted on create); only a set amount, custom_amount, can go on create. Our test restaurant follows that: a suggested tip sent on create isn't applied, and the checkout says why.

Step 3: the restaurant prices each dish

The restaurant echoes each dish with its own titles and prices, and totals the line: (dish + each modification × its quantity) × the dish's quantity. Two ramen at $16 plus a $2 egg each come to $36.

{
  "id": "li_1",
  "quantity": 2,
  "dish": { "id": "ramen_tonkotsu", "title": "Tonkotsu Ramen", "price": 1600 },
  "modifications": [
    { "id": "noodles_thick", "title": "Thick", "price": 0 },
    { "id": "spice_hot", "title": "Hot", "price": 0 },
    { "id": "addon_ajitama", "title": "Ajitama Egg", "price": 200 }
  ],
  "totals": [{ "type": "subtotal", "amount": 3600 }, { "type": "total", "amount": 3600 }]
}

If a required choice is missing, the line stays and the checkout says what to choose (modification_required). If an id isn't on the dish, or one group gets two choices, it's modification_invalid, pointing at the modification.

Step 4: the agent picks the tip

The first answer came back ready to pay at $56.99: the dishes, plus delivery. The fulfillment extension answered with when the restaurant can deliver, the options for the chosen method and the handoff preferences; the tip extension listed the restaurant's suggested tips. The agent then sent one update_checkout: the whole order again, each line by the id the restaurant gave it, with the buyer's 15% chosen from those options:

{
  "food_establishment": { "id": "loc_division" },
  "line_items": [
    { "id": "li_1", "dish": { "id": "ramen_tonkotsu" }, "quantity": 2, "modifications": ["…"] },
    { "id": "li_2", "dish": { "id": "bowl_karaage" }, "quantity": 1, "modifications": ["…"], "note": "sauce on the side" }
  ],
  "fulfillment": { "methods": [{ "type": "delivery", "destination": { "…": "…" },
    "selected_option_id": "delivery-asap", "selected_preference_option_ids": ["pref_hand_to_me"] }] },
  "tip": { "selected_option_id": "tip_15" }
}

An update replaces the checkout's writable state, so everything is sent again, not only the tip. The answer puts delivery and the tip on their own lines in the totals:

"fulfillment": { "methods": [{
  "type": "delivery",
  "options": [
    { "id": "delivery-asap", "title": "As soon as possible",
      "earliest_fulfillment_time": "2026-11-11T11:37:50+00:00",
      "latest_fulfillment_time": "2026-11-11T11:52:50+00:00",
      "totals": [{ "type": "total", "amount": 399 }] }
  ],
  "selected_option_id": "delivery-asap",
  "preference_options": [{ "id": "pref_leave_at_door", "label": "Leave at my door" }, { "id": "pref_hand_to_me", "label": "Hand it to me" }],
  "selected_preference_option_ids": ["pref_hand_to_me"]
}] },
"tip": { "selected_option_id": "tip_15", "options": [{ "id": "tip_10", "unit": "percentage", "amount": 10 }, "…"] },
"totals": [
  { "type": "subtotal", "display_text": "Subtotal", "amount": 5300 },
  { "type": "fulfillment", "display_text": "Delivery (as soon as possible)", "amount": 399 },
  { "type": "tip", "display_text": "Driver tip (15%)", "amount": 795 },
  { "type": "total", "display_text": "Total", "amount": 6494 }
]

The checkout also carries the food-safety notices, each pointing at its dish:

"messages": [
  { "type": "warning", "code": "allergens", "path": "$.line_items[0]", "presentation": "disclosure",
    "content": "Contains gluten, egg, soy, sesame. Cooked in a kitchen that shares equipment, so any dish may contain traces of other allergens." },
  { "type": "warning", "code": "consumer_advisory", "path": "$.line_items[0]", "presentation": "disclosure",
    "content_type": "markdown", "content": "**Consumer Advisory**: Consuming raw or undercooked meats, poultry, seafood, shellfish, or eggs may increase your risk of foodborne illness." }
]

The same order built by hand in Inspect shows each dish with its choices and note, the notices beside it, and delivery and the tip in the total.

Inspect's checkout, ready to pay: Tonkotsu Ramen (Thick · Hot · Ajitama Egg, note "No scallion") ×2 at US$36.00 with the allergen notice and the consumer advisory beside it; Chicken Karaage Bowl (White · Large, note "Sauce on the side") at US$17.00 with its allergen notice; subtotal US$53.00, delivery US$3.99, driver tip (15%) US$7.95, total US$64.94; delivery to 12 SE Ash St, Portland, and the tip options.

Step 5: the agent shows the total and waits

The checkout was ready to pay and the buyer had given the card. The agent didn't complete. It listed each dish with its options, the kitchen note, the allergen notices and the consumer advisory, then the final totals with the tip, and asked for a yes.

The agent's summary: 2x Tonkotsu Ramen with its options, allergen notice and consumer advisory; Chicken Karaage Bowl with its special instructions "Sauce on the side" and allergen notice; subtotal $53.00, delivery $3.99, driver tip (15%) $7.95, total $64.94; "Please confirm if everything looks correct". The buyer replies "Yes, place it."

Play the whole run below, or open it with the full trace.

One run with one model doesn't measure how agents handle food ordering. It shows the pieces arriving where the draft puts them, and one agent using them as intended.

After the buyer said yes, the agent paid $64.94, the checkout's own total. The completed checkout carries the order confirmation: a short label to say at the counter or to the courier, the window it should arrive in, and the page to follow it on.

The run's paid checkout card: Kettle Street Noodles, Delivery, as soon as possible; Tonkotsu Ramen ×2 USD 36.00 (Thick · Hot · Ajitama Egg); Chicken Karaage Bowl USD 17.00 (White · Large, note "sauce on the side"); total USD 64.94; order #1575 and a "Track the order" button.

"order": {
  "id": "01a1ca3e-0f31-7025-bdb9-2be40e72a852",
  "label": "#1575",
  "tracking_url": "https://food.ucpsandbox.com/orders/01a1ca3e-0f31-7025-bdb9-2be40e72a852",
  "earliest_fulfillment_time": "2026-11-11T11:38:47+00:00",
  "latest_fulfillment_time": "2026-11-11T11:53:47+00:00"
}

The agent passed on the label and the link. Food checkout stops there: status updates after the order is placed aren't part of it.

An agent that hasn't adopted it

Ask the food endpoint as an agent whose profile doesn't declare food checkout, and the restaurant refuses it, pointing at the checkout every agent can use:

{
  "type": "error",
  "code": "capabilities_incompatible",
  "severity": "unrecoverable",
  "content": "dev.ucp.food.checkout is not in the capabilities negotiated with the platform's profile (it must declare it at version 2026-08-25). This store's shopping checkout (https://food.ucpsandbox.com/mcp, https://food.ucpsandbox.com/ucp) takes the same menu."
}

That agent can still order through shopping checkout, with dishes as products and add-ons as their own lines, the way the store worked before. A restaurant on more than one platform will meet both kinds of agent for a while.

What isn't in it yet

  • The menu and the cart. Finding a restaurant, browsing its menu and building a cart come later in the council's charter. Until then, ids come from whatever discovery the platform and restaurant share.
  • After the order. Status updates, changes, cancellations and refunds.
  • Allergens as data. A proposal to add per-allergen status and dietary needs to checkout (#964) was closed; reviewers said allergens belong on the menu and the cart. For now they travel as disclosure text.
  • Food discounts. A food discount extension (#992) is in Tech Council review.
  • Several kitchens in one order. Food halls, multi-vendor baskets and group orders are out of scope.
  • Age checks as data. Alcohol hands the buyer to the restaurant's own page (requires_escalation); there's no structured age attestation.

What it means for restaurants and ordering platforms

  • Publish food checkout as its own service, with its own endpoints, if you also offer shopping checkout. The two use the same tool names.
  • Make your menu ids stable and shared: the agent orders by the ids your discovery gives it.
  • Model required choices as modifier groups, and warn when a note asks for something you sell.
  • Send display_text on the tip line, and food-safety notices as disclosures beside each dish.
  • Return a tracking_url on every completed order.

What it means for agent builders

  • Declare dev.ucp.food.checkout (and the extensions you can render) only if you can follow the note and disclosure rules. Declaring it is how you accept them.
  • Ask the buyer for a required choice rather than guessing it, and send each modification once, with its quantity per dish.
  • Keep the buyer's free-text requests in note, and never tell them a note was applied as a change.
  • Choose a suggested tip on update, from the options the checkout returned; only a set amount can go on create.
  • Re-read totals after every update, show the final total with delivery and the tip, and get a yes before completing.
  • After completing, give the buyer the label and the tracking link.

What we'll watch

Food checkout is planned for the 2026-12-08 release. Once it's tagged, we'll watch for restaurants and ordering platforms declaring dev.ucp.food.checkout, how they publish it beside shopping checkout, and whether completed orders carry a tracking link. Until it's in a release, it doesn't change any of our published figures. You can follow what's merged, and what's planned for which release, on our Changes to UCP tracker, and the food vertical on UCP for Food.

FAQ

Does UCP support food ordering?

Yes, in draft. Food Checkout (dev.ucp.food.checkout) was merged into the spec's main branch on 10 November 2026 and is planned for the 2026-12-08 release, a plan that can move. Neither 2026-08-25 nor 2026-04-08 has it.

How is UCP food checkout different from shopping checkout?

A line is a dish with modifications and a note for the kitchen, not a product. A session is bound to one restaurant, fulfillment is delivery or pickup at a time, tips have their own extension, and a completed order returns a label and a tracking link.

How does an AI agent add extras or choices to a dish?

It sends the dish's id with modifications: one id per choice or add-on, each once, with quantity per dish. The restaurant prices them and says when a required choice is missing.

Can an agent use the note field to ask for changes?

Only for requests the menu doesn't model, such as "sauce on the side". A note never changes the price or the modifications, and the restaurant can warn when a note asks for something it sells.

How do tips work in UCP food checkout?

The restaurant lists suggested tips. The agent picks one on an update, once the checkout has returned them, or sends a set amount (custom_amount), which can also go on create. The tip appears as its own line in the totals.

Does UCP food checkout cover menus and restaurant search?

No. Discovery and the menu come before checkout and are left out of this capability. The council's charter puts the menu and the cart in a later phase.

Where can I test an agent against UCP food checkout?

Our test restaurant at food.ucpsandbox.com speaks the draft beside its shopping checkout. You can run any agent against it in UCP Playground, or order by hand in Inspect.


About UCP Checker

UCP Checker is the independent validation and observability layer for the Universal Commerce Protocol. We crawl, validate and grade every public UCP manifest we can find, run the merchant directory, the UCP Score, live adoption stats, the vertical guides and the authority-bound vendor map, and track the spec as it evolves so you don't have to — measured from two vantages (what a business declares, and what actually happens when an agent transacts), the same way for everyone, without picking winners.

Sources

Related coverage: UCP for Food Ordering just got a charter · UCP for restaurants: an operator's guide · UCP subscriptions explained, step by step · UCP list_price explained, step by step

What does a UCP agent find at your store?
Check it once and it gets its own status page.
Check a store

Keep reading

10 Nov 2026 UCP Subscriptions Explained: Purchase Options from Catalog to Order, Step by Step Guides · 12 min 9 Nov 2026 UCP list_price Explained: Reference Prices in Cart, Checkout and Order, Step by Step Guides · 12 min 3 Nov 2026 UCP for B2B: An Agent Buys on Net 30 Terms, Step by Step Guides · 13 min