Coding agents
A coding agent can integrate Layout into your product and prove it against sandbox on its own. A person does the first step, because only a person can create the developer account.
What a person does first
- Sign up at console.layout.link and verify your email.
- On the console's CLI page, choose New token and give the agent the
lcli_token asLAYOUT_CLI_TOKEN. It works in sandbox only, so it cannot reach production or move money. Creating one needs a console sign-in from the last 15 minutes. - If your product will use Sign in with Layout, also create an OAuth client with your redirect URIs, and a sign-in test account, on the console's OAuth clients page. Give the agent the
client_id, the test account's number and its sign-in code.
Everything after that runs from the Layout CLI and the API.
What the agent does
- Installs the CLI with
npm i -g @layoutplatforms/cliand runslayout init --name "<your app>" --json. That finds or creates the application, printsenv.LAYOUT_APPandenv.LAYOUT_SECRET_KEY(ansk_test_key), and runs a simulated test order. It is safe to run again: it finds the same application and never rotates its key. Use it rather thanlayout apps create, which makes a new application on every run. - Picks the way in that fits the product, before writing any code, and says which it chose. Provisioning: your product collects the phone number, then, with your secret, provisions the person (
POST /v1/users), verifies their number (/verify/start, then/verifywith the code they read back) or, when the number already has a Layout account, sends a connect link (POST /v1/users/:id/connect), sends a card link (POST /v1/users/:id/links), and mints a build grant (lgb_,POST /v1/users/:id/grant). Sign in with Layout: the person signs in on Layout's page and your product holds their OAuth access token. The same person gets a different id each way. See Two ways in. - Finds a first place to build at with the person's grant:
layout api get "/v1/places?query=coffee&near=San%20Francisco" --token lgb_... --json. In sandbox it lists only restaurants whose menu Layout holds. An empty list withemptyBecause: "no_held_menu"means none of the matches can take a sandbox cart: search another kind of food or another city, or build at a test restaurant such astest_place_placed. - Builds the order flow on Carts: search
GET /v1/places,POST /v1/cartswith aplaceIdand the person's grant or token, pollGET /v1/carts/:iduntil it isready, show the person the cart, thenPOST /v1/carts/:id/confirmonce they say yes. In sandbox the cart is built at the real restaurant from the menu Layout holds, with no browser, so the same code runs in sandbox and production. - Handles webhooks on your server, and tests them locally with
layout listen --forward-to <your local URL> --secret <whsec> --json, run in the background.--secret, at least 16 characters, keeps one signing secret across runs; without it each run signs with a new one, thesecretof its first line. - Tests every ending at a real restaurant by sending
simulateon the cart, with"latency": "instant"in its tests so nothing waits. - Runs
layout check --forward-to <your webhook URL> --jsonand fixes what it reports until every check passes. When the handler verifies with the secretlayout listenused, it adds--secret <that secret>. An integration that readsGET /v1/ordersinstead of webhooks runs it with--no-webhooks.checkleaves out carts the CLI built, so the application’s own tests use a different test person thanlayout test-order, and never start an idempotency key withcli-.
Sandbox limits
The numbers a test run can reach. Daily numbers count across your developer account and reset at midnight UTC. See Limits.
- People provisioned: 200 a day, and 600 calls to
POST /v1/usersan hour per credential. Provisioning a number the application already provisioned does not count toward the 200, so tests can reuse a fixed test number. - Build grants: 500 a day, and 120 an hour per credential, from
POST /v1/users/:id/grant. A refresh counts toward neither. - Sandbox key reads: 40 a day. With
LAYOUT_CLI_TOKEN, each command that needs the key reads it, so also setLAYOUT_SECRET_KEY. - Sandbox builds: 10,000 a day, at no cost. A build with
"engine": "real"drives the restaurant’s own site and is limited to 10 a day, so tests never send it.
Rules for the agent
- Use only
sk_test_. Ansk_live_secret places real orders and charges real cards with the same code. It never belongs in development, tests or CI. - Keep the secret on your server. Places, menus, item images and carts take the person's build grant or OAuth access token, never your secret.
- Confirm with the cart's
totalMinor, exactly as the cart gives it. The webhook'stotal_minoris the restaurant's total without Layout's service fee, and confirming with it is refused. - Only
placedmeans the order exists. A confirm answersplacing, which can still endfailed.unconfirmedis never a failure: never build it again, and never tell the person it failed. - Send a new
idempotencyKeyfor each new cart and confirm, and the same one when you retry the same request. A confirm sent again with the person's code is the same request: keep itsidempotencyKey. - In sandbox, people have
+1 500 555numbers and the code is000000. Nothing is texted. - An order with
"simulated": truenever reached a restaurant. Never show it to anyone as a real order. - Verify every webhook's signature over the raw body, and skip an
event_idyou have already handled. Never de-duplicate on the order id and event type:order.updatedcan come more than once for one order, each with its ownevent_id. - The pickup time can arrive after
placed. On everyorder.updated, readGET /v1/orders/:id. Showready_etaword for word, never parse it, and show no time while it is null. - Orders are pickup only today. Read
fulfillment.typerather than assuming it. - When a person leaves your product, call
DELETE /v1/users/:id. POST /v1/ordersis retired and answers410. Orders start as carts.
A prompt to start with
Hand this to your agent, or save it in the file your agent reads for project instructions, such as AGENTS.md, or CLAUDE.md for Claude Code.
Integrate Layout into this project so people can order pickup food from it. Read https://docs.layout.link/coding-agents.md first, then https://docs.layout.link/llms.txt for the rest. The OpenAPI spec is https://docs.layout.link/openapi.json. LAYOUT_CLI_TOKEN is set. Run `layout init --name "<our app>" --json` and keep the LAYOUT_APP and LAYOUT_SECRET_KEY it prints in our development environment, never in source control. Pick the way in that fits this product (provisioning, or Sign in with Layout) before writing code, and tell me which you chose. Work in sandbox only. Follow the rules on that page, test every ending with `simulate`, and run `layout check --forward-to <our webhook URL>` until every check passes. Tell me what you could not do.
What the agent cannot do
These stay with a person, on purpose:
- Production. Your person requests it from the console, where a form asks about the company, its policies and the app's listing, and a person at Layout decides it.
layout request-live-accessprints that page's link for them. Thesk_live_secret is revealed only in the console, once the application is approved, and the production signing secret is shown only there too. - Webhook endpoints. Added and removed on the console's Webhooks page.
layout webhooks addandlayout webhooks removealso do it while the application is under review, from CLI 0.4.2.layout listenneeds none. - OAuth clients and sign-in test accounts. Created on the console's OAuth clients page, as above.
- Return URLs. A card link sends the person back only to a return URL registered on the console's App details page. A person adds it there; the CLI cannot. For local tests register
http://localhost:<port>/<path>, which works with the sandbox key only. - Real orders. A real person confirms a real order, with a verified number and a card on their Layout account.