Layout

Money controls

The hard problem in agentic ordering is not placing an order. It is making sure nothing is placed that the person did not agree to, in a system where the thing doing the asking is often a language model.

Every control here is enforced on our servers. Where a control depends on what a host model did, we say so.

The confirmation

Layout builds an order and stops. What comes back is a confirmation naming the restaurant, every item, and the total including Layout's fee, and the host is instructed to show it as written rather than paraphrase it.

Placement is a separate confirm call that names one order and the total the person was shown. Our server checks it against the stored order record, and there is no parameter that skips that check.

What this proves, and what it does not: the server knows a confirm arrived for that exact cart at that exact total from a connection the person authorized. It cannot know whether the person said yes or the host decided they did. Above the code floor below, a texted code closes that gap. Under it, a confirm from a connected assistant is the person's authorization under the Delegated Spending Authority terms, and what bounds a confirm they did not mean is the rest of this page: the price lock, the per order ceiling, the daily limit and the risk check.

The price lock

The total the person was shown is the total the order is placed against. A confirm with any other total is refused, and the refusal deliberately does not echo the stored total, so a host cannot learn the number and retry with it. The only way forward from a changed price is a fresh cart whose total the person sees.

If account credit was shown against the order, it has to still be there at confirm, or the confirm stops rather than charging more than the total shown.

The texted code

A six digit code, texted to the number on the account, is required before an order places when:

  • the order is over $50,
  • the risk check steps the order up,
  • a code has already been sent for that order, so a total that later drops under the floor cannot skip it,
  • an app built on Layout places the order without the person's standing consent, or
  • the account was created by an app and has not been claimed by its owner.

The code is bound on our server to one order at one amount, is single use, and expires in ten minutes. If the amount changes, it no longer matches and is refused. Code sends are rate limited per person and per phone, and wrong guesses are capped.

Today the $50 code floor and the $50 per order ceiling are the same number, so a placed order never crosses the floor on amount alone, and in practice a code comes from the other conditions. They are separate settings: raising the ceiling would not remove the code above $50.

An app's standing consent is given only through a text or page from Layout that says so in words, and disconnecting the app withdraws it.

The risk check

Every confirm is scored before anything moves. The check can let it through, step it up to a texted code, or refuse it outright with nothing confirmed or charged.

The daily limit

Layout will not commit more than the account's daily limit on the person's behalf, across every assistant, app and order, per day. It defaults to $50 and the person can set it between $15 and $150. It is checked at confirm and committed when the card for the order is issued.

The limit is a database constraint as well as a check, so a client cannot widen its own cap. Today's spend is derived from a ledger of committed charges, floored at zero, and a release can only net against a charge that exists. The property the rest of the system relies on is that remaining headroom can never exceed the limit, no matter how many orders are started and abandoned.

A ceiling on every single order

No order is placed above $50 at the restaurant, before Layout's fee, whatever the daily limit says. It is refused in code before the person's card is held, and the refusal is reported rather than swallowed.

The card the restaurant charges

The restaurant is paid with a card Layout holds, issued by Mercury, not with the person's card, so a restaurant's checkout never receives a customer's number. Those cards carry their own spending caps at the bank. The hold on the person's card is the total they confirmed, and is never padded to cover anything on ours.

No card, no payment

The part of Layout that drives a restaurant's checkout does not hold a card and cannot get one on its own. To pay, it asks our servers for one over a connection authenticated by a client certificate, presenting a single use claim our server signed for that order. A claim that does not carry a confirmed amount gets no card. The restaurant's site is also checked against our blocklist at that moment, and the daily limit is committed.

So the question "what stops the automation from paying for something nobody confirmed" has a mechanical answer: there is nothing to pay with. That is the control that still holds when the page it is reading is hostile. See untrusted content.

Duplicates

Every state changing call carries an idempotency key. A repeat with the same key and the same payload replays the stored result instead of doing the work twice, and a repeat with the same key and a different payload is refused rather than treated as new. The fingerprint includes the person, so one person cannot replay another's result by reusing their key.

What is deliberately not a control

We do not score the restaurant's charge with a card network's fraud tools. That charge is made against a Layout card, so a network scoring it would be scoring us, not the person who confirmed the order.

What guards an order today is exactly the list above: the confirmation against a stored total, the price lock, the texted code where it applies, the risk check, the daily limit and its ledger, the per order ceiling, the idempotency key, the claim the automation needs before it can pay, and per person isolation in the database. We would rather name a short list that is real than a long one that reads well.

Updated October 21, 2026