Menu intelligence
What a caller hears priced back, what shows up on the kitchen ticket, and what staff edit on a dashboard are the same underlying record, not three copies that happen to agree today. It’s brought in from what a restaurant already has, checked before it goes live, and honest about exactly what it can and can’t promise once it is.
Nothing goes live by accident
partway through someone’s work on it.
IT COMES IN AS A DRAFT
A restaurant’s existing menu comes in as a draft first, not published sight unseen. Categories, items, prices, and modifiers get reviewed line by line before any of it becomes the record a caller actually hears from.
REVIEWED, THEN PUBLISHED
Sizes, modifier groups, what’s included versus what costs extra, and how many of a given option a restaurant allows are captured explicitly up front — so an order prices correctly the moment it’s placed instead of getting reconciled afterward.
EVERY LATER EDIT, THE SAME WAY
An edit sits as a draft until the restaurant reviews and publishes it. An edit in progress never quietly changes what a caller hears mid-review. Local names get matched too — the way a regular actually orders something is treated as a real way of asking for it, not a mistake that needs correcting first.
“Customize this” is really a few distinct kinds of change.
Underneath “customize this,” a modifier is one of a few distinct kinds of change, each handled on its own terms rather than folded into one generic free-text box. Half and whole: a topping can be asked for on one side only, leaving the other plain. Light, regular, or extra: a modifier carries an actual quantity, not just a present-or-absent flag. A saved preset: a named combination the restaurant has already configured, called up in one request instead of listed piece by piece.
None of this is a blanket “customize as you like” box parsed after the fact. Each kind of change — a side, a quantity, a preset — is its own defined thing, priced and validated as itself.
Mark one component unavailable, and
everything built from it updates together.
Ingredients and components are modeled as shared building blocks, linked to every item that actually uses them — not a flag set by hand on each item, one at a time. That linking is what makes an ingredient running out something the system can actually reason about, rather than something a person has to manually track across an entire menu.
One item on the menu carries no connecting line to any component above and stays available no matter which of them runs out — deliberately included as the control case. Marking an ingredient unavailable never touches an item that was never actually built from it.
Five behaviors, set by the restaurant
An unavailable component is never silently substituted or dropped. Each relationship between a component and the items that use it has its own configured behavior — set by the restaurant, not assumed by anything on Dohos’s side.
The restaurant proposes replacing [original] with [substitute]. This changes [price / ingredients / allergen or dietary status / quantity / other material fact]. The new total is [total]. I will not accept the substitution unless you confirm after reviewing it.
Two of those five are worth being precise about. “Blocks the item” and “blocks the group” differ only in the sentence a caller actually hears — one item goes dark, or a whole configured group does — not in some deeper, separately built process underneath. “Removed, with disclosure” and “optional and unavailable” currently share the same require-an-acknowledgment step behind the scenes. The five names are still real, and still exactly what a restaurant chooses among when it sets this up — the nuance is about what’s shared underneath two of the pairs, not about the choice being smaller than it looks.
Out on the very next call.
Back on the very next call.
An item marked unavailable stops being offered on the very next call, not at the start of the next shift. Restoring it works the same way in reverse — once a component is marked available again, it’s back on the next call too, not queued for some later batch update. Before a change actually publishes, its real scope is shown — every item and group it touches — so marking one ingredient unavailable is a decision made with the full picture in front of someone, not a guess at what else happens to use it.
One ingredient running out, mid-shift
Partway through a dinner rush, a restaurant runs out of mozzarella. A staff member marks it unavailable from the screen built for exactly this moment, and before that change goes live, the same screen shows every item and group it actually affects — the real list, not a guess.
A caller who dials in a few minutes later asking for a calzone hears the truth plainly: mozzarella is out, and a substitute the restaurant already configured — provolone, at a price recalculated for the swap — is offered instead, still subject to that caller’s own confirmation before it’s accepted. A different caller, ordering garlic knots at the very same moment, hears nothing about any of this. Garlic knots never depended on mozzarella in the first place, and running out of one ingredient never reaches an item it was never actually built from.
A price doesn’t live in three places
that can quietly drift apart.
It lives once, in the published catalog, and everything else is a reflection of that one record rather than an independent copy someone has to keep in sync by hand.
THREE SURFACES SHOW THE SAME NUMBER BECAUSE THEY READ THE SAME RECORD — NOT BECAUSE SOMEONE KEPT THREE NUMBERS MATCHED BY HAND · A SAMPLE RECORD, NOT A REAL MENU
And the one place this page
needs a careful read.
What if the menu online doesn't match what's actually available?
The record behind a call is the same one everything else reads from. If a change hasn’t been published yet, it hasn’t taken effect anywhere yet either — including on the next call.
Can it invent a substitution I didn't ask for?
No. Only a substitution the restaurant specifically configured is ever offered, and it still needs a caller’s own confirmation before it’s accepted — nothing is swapped in silently.
Does it work for a menu that isn't pizza?
Yes. The underlying catalog and pricing engine has no food-specific logic built into it anywhere — the same engine has been proven end to end against a genuinely different kind of menu, not just a pizza one, with nothing rewritten to make it work.
What about a gluten-free or vegan label?
A label like that is read back exactly as the restaurant wrote it — never upgraded into a safety guarantee it was never meant to be. See the honest limits below for exactly where that line sits.
Nothing here is a safety guarantee — menu labels and an AI response can’t guarantee an item is safe for a specific allergy or sensitivity. A “gluten-friendly” label is never converted into “gluten-free,” and an ingredient’s absence from a description is never treated as proof there’s no cross-contact risk.
If this is an allergy or a serious sensitivity, menu labels and an AI response cannot guarantee safety or prevent cross-contact. I can share the restaurant’s current statement and try the verified restaurant contact option, but please do not rely on me to decide whether the item is safe for you.
The available restaurant information is missing or conflicts about [fact]. I can’t resolve that safely. I won’t describe the item as meeting the request unless the restaurant confirms it.
For a genuine allergy concern, the honest answer is always to confirm directly with the restaurant itself — never to rely on a best guess about what’s actually in a dish.
GO DEEPER
Orders
Sizes, halves, swaps, allergies — the whole order, read back in full for a yes.
OPEN →PLATE Nº 011Staff view
The tablet by the pass: queue, wait, 86 board — zero training course.
OPEN →PLATE Nº 009Questions
Hours, parking, gluten-free — answered from what you actually published, never guessed.
OPEN →See it run on a real menu.
Request access and watch the cascade run on your own menu, not a demo one.