Layout Documentation

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 a language model.

Every control here is mechanical. A gate a model can talk itself out of is not a gate.

The confirmation

Layout builds an order and stops. What comes back is a confirmation naming the restaurant, every item, and the total, and the host assistant is instructed to relay it exactly as written rather than paraphrase it.

Placement is a separate call that references a specific order and the total the user agreed to. Our server checks the confirmation against the stored order record, so no phrasing in a conversation satisfies it, no host model can decide it has been satisfied, and there is no parameter that skips it.

The price lock

The total the user approved is the total the order is placed against. If the amount has changed between the confirmation and the placement, the placement does not quietly proceed at the new number.

The texted code

A user may require a fresh six digit code, texted to the number on the account, before an order places. The code is bound server side to one order at one amount and expires in ten minutes. If the amount changes, the code no longer matches and is refused.

New accounts start with codes off, so a confirmation is one tap, and the choice is recorded as an agreement rather than a preference toggle. The toggle reaches orders at or under fifty dollars only: above that figure the code is enforced regardless, as is a risk step up. Whether a code was demanded is stored on the order itself, so flipping the setting mid flow cannot skip a challenge the account was already given.

The daily limit

Layout will not commit more than the account's daily limit on the user's behalf, across every assistant and every order, per calendar day. It defaults to fifty dollars and the user can set it between fifteen and one hundred and fifty.

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 refunds can only ever 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 a user starts and abandons.

A ceiling on every single order

No single order is placed above fifty dollars, whatever the daily limit says. It is refused in code before a bank is contacted, and the refusal is reported rather than swallowed. The card rail is early production and this is the bound we would rather have than a story about how careful we are.

The card the merchant charges

The restaurant is paid with a Layout virtual card, not the user's card, so a merchant's checkout never receives a customer's number.

That card carries a small allowance over the approved total, because a restaurant's own tax line is added by their checkout and a card authorized for exactly the cart total would decline at the last step. The allowance is sized to clear the highest combined sales tax in the country rather than picked for comfort. It is headroom on our side and not something the user is charged for: the hold on their card is the total they approved and is never padded to match.

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. It has to ask our servers for one, presenting a claim we minted for that specific order, over a mutually authenticated connection. We only mint that claim for an order that has been confirmed and is inside the account's limit, and the claim is what binds a card to that one order.

So the question "what stops the automation from paying for something the user did not approve" has a mechanical answer rather than a behavioural one: there is nothing to pay with. That is the control that still holds when the page it is reading is hostile, which is the case a well written instruction does not cover. 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 user, so one user cannot replay another's result by reusing their key.

What is deliberately not a control

We do not score the food charge with a card network's fraud tools. The charge a restaurant makes is made against a Layout card, so a network scoring it would be scoring us, not the person who confirmed the order. Claiming that guardrail would put a control on a diagram rather than in the code.

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

Updated September 2, 2026