- Brand
- Layout
- Category
- Commerce
- Primary Subcategory
- Restaurant Delivery & Food Ordering Aggregators
Integration details
Description
Layout lets you order real food from restaurants without leaving ChatGPT. Tell it what you're craving and it handles the whole order for you, from picking your items to checking out. No hopping between apps, no re-typing your order, no digging through menus. You stay in the chat and the food comes to you.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Restaurant Delivery & Food Ordering Aggregators
- Secondary Subcategories
- None listed
- Brand
- Layout
- Access
- Account required
- First tracked
- 2026-09-13
- Tool count
- 10
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Layout
Get updates when Layout’s Discoverability Score or category rank changes.
Competing in ChatGPT Restaurant Delivery & Food Ordering Aggregators
View Category10 tools agents can invoke
Look up something SPECIFIC on a restaurant's LIVE menu — read from their own ordering site, so items and prices are real, not from memory. Layout is built for TARGETED lookups ('do they have a spicy chicken sandwich', 'how much is a large fry', 'what tacos do they have'), NOT for dumping an entire menu — restaurant sites hide most of their menu behind sections, so a whole-menu request usually returns a fraction of it and reads as incomplete. ALWAYS NARROW FIRST: if the user has not named a dish, section, or budget ('what's on the menu?'), do NOT call this tool yet — ask what they're after ('Anything in particular — burgers, tacos, something cheap?'), then call it with `query` naming the restaurant and `category` set to the section they want. Use it BEFORE building an order whenever the user asks what's available, wants a price, or asks for a specific item/size/count. RECOMMENDATIONS DON'T NEED A LIVE READ: for 'what should I get at X' / 'what are they known for', pass `mode:'knowledge'` — it answers from web knowledge in seconds and opens no browser. It is a metered web lookup, so ask it once per restaurant, not every turn. Save the live read (the default) for an exact price, size, or availability, and for confirming an item exists before you build an order. Pass the restaurant name (plus the user's area or geo), or the orderUrl from an earlier order preview. Prices are in cents (priceMinor). If status is 'unreadable', Layout couldn't read the menu this time — say so plainly and offer to order the item directly instead; NEVER present guessed or remembered menu items as if they came from this tool. If status is 'knowledge', Layout couldn't read the LIVE menu but looked the restaurant up on the web — relay `sayToUser` (it already says it's general, non-live info and that prices vary); present it as background, never as their live menu or exact current prices. CHOICES ON AN ITEM: an item may come back with `optionGroups` — the choices the restaurant itself attaches to it, in their words, with `required` saying whether their site demands an answer. That is the ONE source you may raise a choice from: offer those option names exactly, never sizes or add-ons you remember. A group's `defaults` are what the item comes with, as on the restaurant's own page: the item is ordered that way unless the user asks for something else, so don't ask them to pick it again. An item with NO `optionGroups` field means Layout could not read whether it has any — say nothing about choices for it rather than claiming it needs none. PRESENTING RESULTS: relay what's relevant to the user's ask, not the whole list — if they asked for sandwiches, show the sandwich options; only walk the full menu if that's what they asked for. If the exact thing they wanted isn't there, say so and offer the closest categories that ARE ('no sandwiches, but they have burgers'). FORMAT IT CLEANLY: present items as a short scannable list, one per line, item name then price (convert priceMinor cents to dollars, e.g. 289 -> $2.89) — group under section headings when there is more than one section. Never paste raw JSON, never show cents-integers, never write it as a paragraph, and do not pad it with commentary between items. Lead with one short sentence, then the list. NO PRICES: if pricesUnavailable is true, the items are real but their site withheld pricing — relay sayToUser, list what they have if useful, and NEVER fill in prices from memory or treat a missing price as free. STILL READING: if status is 'reading', the menu is being read right now on the restaurant's site. Relay sayToUser if it is present (it says what is actually taking time) and otherwise say nothing, then call this tool AGAIN with the SAME arguments to collect the result — repeat calls attach to the read already running, so they are free and start nothing. Each repeat call WAITS with the read (up to ~20s) rather than returning instantly, so call it again immediately and do not add delays or give up early. Keep going until status is 'menu' or 'unreadable'. Say NOTHING on a poll unless sayToUser is present — it is absent on purpose most of the time, and Layout sends at most a couple of updates for one read. Read-only: never orders, never charges. Menu reads are limited per user per day — if the limit is hit, say so and order directly instead.
menu
Check on an order that is already running. READ-ONLY and free: it never places an order, never charges anything, never starts or retries a build. Call it as often as you need. NOT FOR NEW REQUESTS: when the user just ASKED for food, call `order` (preview/build) — this tool only reports on work already started, and a 'cart_expired' answer here means the old cart is DEAD: never present its card; start a fresh build with a NEW random idempotencyKey. HANDLES: pass `idempotencyKey` to follow a CART BEING BUILT (the key you used for 'build'), or `orderId` to follow a PLACEMENT (after 'confirm' returned status 'placing'). IF YOU NO LONGER HAVE EITHER — a new turn, a lost key — CALL IT WITH NO ARGUMENTS AT ALL: that means 'the build this user has running', which is almost always the right question. Never tell the user you cannot check because you lost a key; just call this with no arguments. When nothing is running, the same no-argument call returns `recent`: the user's own order attempts from the last two days, each with a `summary` to relay. Use it when they ask about an earlier order you cannot see, and never raise an attempt they did not ask about. THIS CALL LONG-POLLS: it waits up to ~25 seconds and returns the moment something changes, so when it comes back still 'building' or 'placing', call it again right away — do NOT add a delay of your own, and do not narrate every poll. Relay the FIRST 'building' message to the user (with its trackUrl), then poll quietly. WHEN TO STOP: a build is done at 'carted' — the response carries `confirmationCard`, which you present to the user VERBATIM. A placement is done at 'placed' or 'failed'. 'placed' is the ONLY status that means the order exists; never tell the user it was placed on anything else. 'challenge' means the purchase needs the cardholder's own approval. READ `smsSent` BEFORE SAYING ANYTHING ABOUT A TEXT: true means a secure link was sent, so tell them to tap it and keep polling; false means it could NOT be sent, so say exactly that and tell them to open the Layout app to approve. Never say a link was texted without `smsSent === true` — a person told to tap a link that was never sent is being asked to wait for something that is not coming. 'unconfirmed' means Layout could not verify either way: say exactly that, and do NOT re-order. If you cannot keep polling on your own, tell the user it is still running, give them the `trackUrl`, and ask them to check back — their next message picks it up with one call.
order_status
Find restaurants, cafes and coffee shops BY DESCRIPTION OR NAME — 'is there a Starbucks in Oakland', 'coffee near me', 'somewhere open for breakfast', 'taco places downtown'. Use it whenever the user asks WHAT IS THERE rather than asking you to order: it answers from the restaurants Layout already holds, so it is free, instant, and real. Pass `geo` whenever you have the user's coordinates and `near` when they NAMED a place ('in Oakland') — a named place is where they are asking ABOUT, which is not always where they are. WHICH TOOL: use this for 'what is there' (no personalization, anyone gets the same answer); use `discover` for 'where should I eat', which is drawn from this user's own order history; use `menu` to read what a specific restaurant SELLS, which opens their site and is metered. This one never orders, never charges and never opens a browser. THE FIELDS ARE THE FACTS. Every field returned is stored data: relay the name, address, cuisine, rating, distance and open-now as given, and never add a fact Layout did not return (hours, distance, whether a place exists, what the building has). When the user asks which one to pick, pick one and say why from those fields; what a chain or kind of place is generally like may inform the why, said as general knowledge and never as something Layout checked. For what ONE place is known for or what to order there, call `menu` with mode 'knowledge'. HOURS ARE PART OF THE ANSWER, NOT AN EXTRA. Every place carries `openStatus`: 'open', 'closed', or 'unknown'. Results already lead with the open ones, so RECOMMEND FROM THE TOP and never present somewhere that is shut as a place to go right now. Say `closesAt` when you have it — 'open until 5' is the answer somebody can act on, 'open' is not. When they asked about ONE SPECIFIC PLACE, give them its status straight: 'they're closed, they open again at 7' or 'open until 9'. 'unknown' means Layout holds no hours for that place — say you do not know its hours, and NEVER report it as closed or imply it is open. `openNow` is the same answer as a boolean for older clients; prefer `openStatus`, whose null case has a name. AN EMPTY LIST IS AN ANSWER, UNLESS `stillChecking` OR `notOpenNow` SAYS OTHERWISE. `stillChecking` means Layout found places there and has not finished working out whether they take online orders, so an empty or short list is not the whole story: say you are still checking, offer to look again in a moment, and never say there is nothing there. `notOpenNow` means Layout DID find real restaurants there and every one of them is closed right now — that is why `places` is empty, and saying there is nothing near them is false. Tell them nothing is open, read the first `notOpenNow` row's `opensAt` for when the earliest one opens, and offer to look further out. Never offer one of those as somewhere to go now, and never promise to tell them when it opens: Layout cannot schedule, wait or message anybody. With neither flag, say Layout has nothing matching and offer to widen the search — never fall back to restaurants you know of, which would present your own guess as Layout's answer. To order from one, call `order` with its name and address.
places
Answer a question ABOUT LAYOUT ITSELF from Layout's own published help centre — refunds, when and how the user is charged, spending limits, changing or cancelling an order, what happens when an order is wrong or late, card safety, what data Layout stores, profile and dietary preferences, where Layout can order from, and how to set Layout up in an assistant or on a phone. CALL IT WHENEVER THE USER ASKS HOW SOMETHING WORKS, what a policy is, or whether they will be charged for something — and do NOT answer those from memory: Layout's policies are Layout's, you cannot know them, and a confident wrong answer about somebody's money is the worst thing this surface can do. Every result carries the article's `url`: give it to the user with your answer so they can read the real page. AN EMPTY LIST IS AN ANSWER — it means Layout has published nothing on this, so say you do not know and offer support rather than inventing a policy or paraphrasing one from another food app. Free, instant, read-only: it reads stored articles, orders nothing and charges nothing. WHICH TOOL: this one is about LAYOUT; `menu` and `places` are about RESTAURANTS; `order_status` is about one specific order the user placed.
help
Read or update the user's Layout food profile — the preferences Layout applies to every order: dietary restrictions ('vegetarian', 'no shellfish'), favorite restaurants, usual orders, the first name orders go under, and whether dietary restrictions are applied automatically. Use 'get' to read it; use 'update' when the user states a LASTING food preference ('I'm allergic to peanuts', 'my usual at Chipotle is a chicken bowl') so future orders respect it. Ask before saving anything the user didn't clearly state, and tell them what you saved. Remove a note by its id from 'get'. This tool never orders and never stores payment or contact info. Phone number, email, addresses and cards can NOT be viewed or changed here by design — when the user asks about those (or asks to 'manage my account'), reply in ONE short sentence with the link — e.g. "That's managed on your Layout account page: https://account.layout.link" — and stop. Do NOT enumerate what this tool can or can't do, and do NOT explain the design; answer the question, give the link, done.
profile
Place or preview a food order for the user. FLOW: 'preview' resolves a restaurant + estimates cost. 'build' STARTS building a real priced cart (it runs in the background and returns {status:'building'} immediately — building can take 1-3 minutes on a new site). Then poll 'status' with the SAME idempotencyKey until it returns the cart (status 'carted'). NOTE: 'status' LONG-POLLS — each call blocks up to ~25s while it waits, so just call it again right after it returns 'building' (don't add your own delay, and don't announce every poll — poll quietly and only tell the user when the cart is ready or if it's taking a while). When status is 'carted', the response includes a `confirmationCard` — Layout's branded confirmation text (store, items + modifiers, total, card last-4, pickup time, and a confirm prompt). PRESENT `confirmationCard` TO THE USER VERBATIM, exactly as written — do NOT rewrite, summarize, reorder, shorten, or add to it; it is Layout's interface and you relay it, you do not author it. A confirmation code is texted to the user; then 'confirm' finalizes with the code they read back (stage 'confirm'), or stage 'resend' for a new code. PLACEMENT (after confirm): when 'confirm' returns {status:'placing'}, the order is being PLACED live — tell the user you're placing it, then IMMEDIATELY poll 'status' passing the `orderId` (NOT the idempotencyKey) and keep polling until `placement.status` is 'placed', 'failed', or 'challenge'. Each orderId poll long-polls ~25s — call it again right away, quietly. Report ONLY what placement returns: 'placed' → the order is in (relay its userMessage); 'failed' → relay its userMessage, nothing was charged; 'challenge' → the user was TEXTED a secure verification link — tell them to tap it, then keep polling. NEVER say the order is placed or charged before placement.status says 'placed'. If status is 'reached_bag_only', we could NOT confirm the cart contents and nothing was placed — relay its `userMessage` and do NOT claim an order was placed or priced. If status is 'paused', this purchase needed an extra confirmation step and we TEXTED the user a secure link — present the `confirmationCard` (item + total) and tell them to tap the texted link to approve; do NOT ask for a 6-digit code (the link is the confirmation, not a code). NEXT-DAY PICKUP: if a carted response includes a `pickupWarning`, the restaurant is closed now and the earliest pickup their site offers is next-day (or later). Present the `confirmationCard` AND relay `pickupWarning.message` so the user sees the pickup time before deciding — confirming the cart means accepting that pickup time. If status is 'closed_next_day' (no cart was built yet), relay its `userMessage` and ask whether they still want it or would rather find an open spot — this is a yes/no DECISION, NOT a 6-digit code; on a 'yes' start a fresh build (new idempotencyKey) as they asked. If any action returns status 'platform_offline', Layout is in scheduled maintenance right now — relay its `userMessage` to the user VERBATIM (it states when we'll be back + an info link). Do NOT retry, do NOT start a build; nothing was ordered. If build/status returns order_in_progress, the user already has ONE order building (only one at a time) — relay its userMessage and do NOT start another build; poll the EXISTING build's key instead. CRITICAL — DO NOT AUTO-RETRY: each build spends a real, billed browsing session. If a build ends in error/timeout/reached_bag_only, STOP and tell the user what happened; do NOT start a new build on your own. Only build again if the USER explicitly asks you to try again — and only then set userInitiatedRetry:true. If build returns retry_blocked, a recent attempt just finished and an automatic retry was refused — relay its userMessage and wait for the user. Never loop builds hoping one works. None of these place or pay (that comes later). LOCATION CHAIN (highest confidence first): (1) if you have the user's DEVICE coordinates, pass `geo` {lat,lng} — Layout resolves the nearest store to it; (2) else a location the user STATED — pass their EXACT words incl. any street address in `near`; (3) else OMIT both — Layout uses their saved account address; (4) if preview returns needsLocation, relay `sayToUser` — it already includes the 2-3 nearest store guesses (from `nearby`) for the user to pick from. When the user names a specific store address, ALWAYS pass it through in `near` and `restaurantAddress` — never swap in a different location. KEYS: generate a FRESH RANDOM idempotencyKey for every NEW order attempt (include 8+ random characters — a key derived only from the date/food collides with earlier sessions). Reuse a key ONLY to poll or confirm that SAME attempt. If build says the key already exists, that's a PREVIOUS attempt — start a fresh build with a NEW random key. PRICE INTEGRITY: the ONLY total you may pass to 'confirm' is the Total on the confirmationCard the user approved. If confirm returns price_changed, NEVER retry with a different expectedTotalMinor — relay its userMessage and rebuild fresh (new key) so the user approves the current price on a new card. LANGUAGE: preview returns `sayToUser` — use its framing with the user. NEVER use internal terms with the user: no 'cold/warm site', 'mapped', 'lane', 'spec', 'agent', or internal cost numbers (feeUsd is the only user-visible fee). Prefer the `sayToUser` framing (first visit ≈ 'around 2–3 minutes, I'll message you here when it's ready'; return visit 'should be quick, I'll message you when it's ready').
order
Get the user's location when you don't already have it — use this the moment they ask for something NEARBY ('near me', 'around here', 'closest one') and you have no coordinates and they named no place. It returns coordinates you then pass to `places`/`order`; you never see or handle the raw fix yourself. IF THE USER'S HOST ALREADY GIVES YOU THEIR LOCATION (some phone apps do), you do NOT need this — just search. Call this only when you are location-blind. WHAT COMES BACK: if `located` is true, you have their location — continue silently, do NOT read the coordinates out loud. If `located` is false and there is a `shareUrl`, RELAY the `userMessage` (with its link) VERBATIM and STOP: they tap it once to share, and this call already waited for that tap, so a false result means they haven't tapped yet. When they say they've shared it, call this again (or just retry what they asked). NEVER guess a city and NEVER name places from memory when you are blind.
get_location
Show what ONE menu item at a restaurant looks like, using the photo the restaurant itself published (screened, and never a stock or AI image). Use it — not `order`, not `menu` — whenever the user asks to SEE an item: 'show me', 'what does it look like', 'can I see a picture', 'what does the iced latte look like at Blue Bottle?', or yes after you OFFERED a look. Asking to see an item is not asking to order it: do not offer to order in the same breath. Do NOT call it unprompted for every item you mention: offer once ('Want to see it?') and call only on a yes. One item per call. Display only: it says nothing about price or availability today; use `menu` for those. `item` must be a dish the USER named. If they named only a restaurant ('show me a panda', 'what about Chipotle'), do NOT pick a dish for them: ask which one. A restaurant name alone ('a panda') is a restaurant, not an item.
item_photo
Recommend WHERE the user should eat, drawn from what they have actually ordered through Layout. Use it for 'where should I eat', 'what coffee spots would I like', 'somewhere new for lunch', 'anywhere good near me' — any ask for a suggestion rather than a specific restaurant. Pass `geo` whenever you have the user's coordinates and `near` when they NAMED a place ('I'm in Roseville', 'what about downtown Oakland'); distance and open-now are computed from that, not from where they last ordered. Read-only: it never orders and never charges. EVERY SUGGESTION COMES WITH ITS EVIDENCE. `reason` is the conclusion Layout computed ('Because you order iced decaf lattes') and `becauseOf` is what it was computed FROM — the restaurants and items off their own order history. Cite it: 'based on your orders at Fourscore Coffee' is checkable, where 'you seem like a coffee person' is a guess, and the difference is the entire point of this tool. Relay `reason` as given. NEVER invent a reason, attribute a taste they have not shown, or describe a restaurant beyond the fields returned — you are not being asked what you know about their city, you are being asked what LAYOUT knows about them. AN EMPTY LIST IS AN ANSWER, NOT A FAILURE. `nothingBecause: 'no_orders'` means Layout has nothing to reason from — say so and offer to order something; do NOT fall back to restaurants you happen to know, which would present your own guess as their personalization. `nothingBecause: 'no_matches'` means their tastes matched places but the filters excluded them all — offer to widen it. HOURS ARE PART OF A RECOMMENDATION. Each place carries `openStatus`: 'open', 'closed' or 'unknown'. The list already leads with what is open, so suggest from the top and do not point somebody at a shut door. Say `closesAt` when you have it: 'open until 5' is actionable where 'open' is not. 'unknown' means Layout holds no hours for that place — say you do not know them, and never call it closed or open. Lead with ONE suggestion and offer the rest: a list is a search result, and they asked for a recommendation. WALKING DISTANCE IS A CONSTRAINT. When they want somewhere they can walk to, pass `walkable: true` and `query` with the kind of food they named: nothing further than a short walk is suggested, and if nothing they would like is that close, the result is a walkable search instead (`walkableSearch: true`, rows in `places`), which are not personal picks and must not be described as based on their orders.
discover
Answer an EVALUATIVE question about ONE restaurant you already have a `placeId` for — 'is it vegetarian', 'can I sit down there', 'do they do takeout', 'is it good for a group', 'do they serve breakfast'. It reads the food and beverage attributes Layout holds for that place, so it is free after the first lookup, instant, and real. WHICH TOOL: use `places` to FIND a place or ask what is there / open / how far; use this once you have a specific place and the user asks what it's LIKE. Pass the `placeId` from a `places`, `discover` or `order` result — if you don't have one, call `places` first; this tool never resolves a name (that would cost a search). It never orders, never charges, never opens a browser. REPORT, DO NOT EMBELLISH. Every field is stored data and three-state: true/false you may relay, `null` means Layout does not know — say you cannot tell, and NEVER report a null as the place NOT having something. WHAT IT CANNOT DO: it does not say how HEALTHY or how GOOD a place is — Layout holds no such field. For 'is it healthy', the only honest signal is whether it serves vegetarian food; say that and say you cannot rate healthiness. For 'is it any good', use the rating from `places`. Do not invent attributes from what you remember about the place or the chain.
place_facts
Layout ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Layout's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Layout alternatives on ChatGPT?
As of 2026-10-26, Layout competes with BhojMandu, Bites, Botala by dyskute, Dominio Tech Delivery, Fantuan, foodora, foodpanda, Glovo and 15 more in ChatGPT Restaurant Delivery & Food Ordering Aggregators, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.