{
  "openapi": "3.1.0",
  "info": {
    "title": "Layout Partner API",
    "version": "1.0.0",
    "summary": "Place real pickup orders at the restaurants Layout orders from.",
    "description": "Provision a user, find a restaurant, read its menu, build a cart, and confirm it. REST and MCP are two doors to the same ordering: the same engine, the same checks and the same money rules behind both. Layout drives the restaurant's own ordering site, so there is no merchant integration and no menu to sync.\n\nTwo kinds of credential. An application secret (`sk_test_` for sandbox, `sk_live_` for production) provisions people and reads orders and events. Sandbox runs the real engine against real restaurant sites and finishes every order as a simulation: it never places or charges. Its test restaurants (`test_place_` ids) script one outcome each and never open a browser. Production access is reviewed by hand; until it is granted, a live key is refused with 403. A person credential acts for one person: an access token from a person who connected your application through Layout's OAuth consent (issued for the resource `https://api.layout.link`), or a build grant (`lgb_`) from POST /users/{userId}/grant. A person credential reads, builds and confirms carts, and every confirm meets the same checks as every other way to order through Layout. On a connected person's token, the 6-digit code Layout texts that person is asked for when the restaurant's total is over Layout's amount limit for codes, which can change, Layout's risk checks call for one, or a code is already out for that order. A live build grant meets the same rules: connecting your application is the person's agreement that it places orders for them (for a person who connected before that, the first order's code says so and agrees to it). When a code is asked for, Layout texts it to the person, naming the total and the store, and you send it back on the same confirm. A build grant never adds a card, and confirms only carts your application built. In sandbox its confirm is a simulation.\n\nEvery error these endpoints send has the same shape, `{ \"error\": { \"code\", \"message\" } }`, and `code` is one of a published list. A 401 and a 403 read the same whatever the reason; the real reason appears on the application's Refusals page in the console. Three answers come from in front of the endpoints and are flat, `{ \"error\": \"<code>\" }`: a request no endpoint handles (404 `not_found`), a write carrying a browser `Origin` Layout does not allow (403 `bad_origin`), and an outage at Layout's edge (503 `unavailable`).\n\nEvery answer from an endpoint carries `X-Request-Id`, Layout's id for the request, and `Layout-Version`, the dated version that answered. Send `Layout-Version` to pin one; without it you get 2026-10-01. Every POST takes an `Idempotency-Key` header: a retry with the same key and body gets the stored response for 24 hours and never runs twice.",
    "contact": {
      "name": "Layout",
      "url": "https://docs.layout.link"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://layout.link/legal/terms-conditions"
    }
  },
  "servers": [
    {
      "url": "https://api.layout.link/v1"
    }
  ],
  "tags": [
    {
      "name": "Users",
      "description": "People you can order for."
    },
    {
      "name": "Places",
      "description": "Restaurants Layout can find."
    },
    {
      "name": "Menus",
      "description": "A restaurant's live menu."
    },
    {
      "name": "Images",
      "description": "Photos restaurants published of their menu items."
    },
    {
      "name": "Carts",
      "description": "Building a cart for one person, and confirming it."
    },
    {
      "name": "Orders",
      "description": "Reading outcomes."
    },
    {
      "name": "Events",
      "description": "Poll parity with webhooks."
    },
    {
      "name": "Usage",
      "description": "Your limits and what you have spent against them."
    },
    {
      "name": "Sandbox",
      "description": "Test restaurants and test events, in sandbox only."
    }
  ],
  "paths": {
    "/whoami": {
      "get": {
        "tags": [
          "Users"
        ],
        "operationId": "whoami",
        "summary": "Readiness check",
        "description": "What the credential resolves to. An application secret answers `kind: app` with its environment and approval status; a connected user's token answers `kind: user`; a build grant answers `kind: grant`.",
        "security": [
          {
            "appSecret": []
          },
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "Who you are.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Whoami"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The credential was not recognised.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not call this.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials could not be checked right now.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users": {
      "post": {
        "tags": [
          "Users"
        ],
        "operationId": "createUser",
        "summary": "Provision a user",
        "description": "Idempotent on phone number: calling twice returns the same user rather than a duplicate. Mints nothing that can spend.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created, or the existing user for this phone number.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              },
              "Deprecation": {
                "description": "RFC 9745: something in this answer is deprecated, since this moment as `@` and Unix seconds. It keeps working under every version Layout answers today.",
                "schema": {
                  "example": "@1792540800",
                  "type": "string",
                  "pattern": "^@\\d+$"
                }
              },
              "Link": {
                "description": "`rel=\"deprecation\"`: the page that says what to use instead.",
                "schema": {
                  "example": "<https://docs.layout.link/changelog/verifying-makes-the-account>; rel=\"deprecation\"",
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`provisioned_to_another_app`: this number is already provisioned to another application in your developer account, in the same environment. A number belongs to one application at a time. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-hour or per-day provisioning ceiling.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}/verify/start": {
      "post": {
        "tags": [
          "Users"
        ],
        "operationId": "startVerification",
        "summary": "Text the person a verification code",
        "description": "Sends a six-digit code to the number you provisioned, good for three minutes from this send and for five tries. The person reads it back to you. A new send replaces the last one. A person already connected to this application gets a fresh code too, so a returning person on a new device can be recognised; the code only proves they hold the phone and never signs them in to Layout.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "responses": {
          "200": {
            "description": "Code sent.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyStarted"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`already_claimed`: this person claimed their own Layout account without connecting this application; get a consent link from POST /users/{userId}/connect. `phone_changed`: the person's Layout account no longer holds the number you provisioned; you stay connected under this id, and headless verify is unavailable until their account holds this number again. `texts_blocked`: the number replied STOP to Layout, so no code can be texted; the person replies START to the number Layout texts from, then you start again. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "This user has no usable phone number on file.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A verification ceiling: a cooldown on this number, your developer account's hourly or daily text allowance, or Layout's hourly limit across every developer. The allowance and Layout's ceilings carry `error.limit`; an hourly one has `period: \"hour\"`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "The code could not be sent. Nothing was spent; retry.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}/verify": {
      "post": {
        "tags": [
          "Users"
        ],
        "operationId": "verifyCode",
        "summary": "Submit the code the person read back",
        "description": "Checks the code against the last one Layout texted for this person and answers their per-application `id`. Returns no session. For a person already connected, a right code answers the same `id` as before and changes nothing; call verify/start first to text them one. Sent with no code, a person already verified answers `verified: true` without a check, so only an answer to a request that carried a code proves the person holds the phone. Read `authorized` before building.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verified.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Verified"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: a six-digit code is required. `code_expired`: no code was texted for this person in the last three minutes, or the last one took five wrong tries; text a new one with verify/start. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`bad_code`: the code is not the one Layout texted; ask the person for the current one. Each try counts toward the five a text allows. `unauthorized`: the secret was not recognised.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "This user has no usable phone number on file, or, in sandbox, no reserved test number.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts for this number.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}/connect": {
      "post": {
        "tags": [
          "Users"
        ],
        "operationId": "connectUser",
        "summary": "Get a consent link for an existing Layout account",
        "description": "Returns a link to the Layout consent screen for someone who already has a Layout account. Nothing is attached until they approve.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A consent link, or already connected.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectLink"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute ceiling.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}/grant": {
      "post": {
        "tags": [
          "Users"
        ],
        "operationId": "createGrant",
        "summary": "Mint a build grant token",
        "description": "A build grant for one person, for MCP or the REST person routes. It reads places and menus, builds and reads carts, releases a cart it built, and confirms after the person says yes, with the 6-digit code Layout texts them whenever one is due (`codeReason` on the cart says why), which the person relays to you. It cannot add a card. GET /orders/{orderId} reads only the orders this application's grants built for that person. A sandbox grant confirms as a simulation that places and charges nothing, with no code except at `test_place_code` (`000000`). A grant lasts 15 minutes. To keep a session going, send the current grant as `refresh` before it expires: the same token lasts another 15 minutes, up to 24 hours from when it was minted, and no build-session allowance is drawn. The body is optional.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GrantRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The grant sent as `refresh`, extended.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Grant"
                }
              }
            }
          },
          "201": {
            "description": "Token minted. Returned exactly once.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Grant"
                }
              }
            }
          },
          "400": {
            "description": "`refresh` is not a build grant token. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`already_claimed`: that person has claimed their own Layout account. `grant_expired`: the grant sent as `refresh` expired, was revoked, belongs to someone else, or is 24 hours old; mint a new one without `refresh`. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "The build-session ceiling. A refresh does not count toward it.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}/links": {
      "post": {
        "tags": [
          "Users"
        ],
        "operationId": "createCardLink",
        "summary": "Mint a card link",
        "description": "A short Layout page where the person adds a card to their Layout account, with no Layout sign-in, then returns to your app. Send it as a link, or open it in a sheet (ASWebAuthenticationSession or SFSafariViewController on iOS). The card goes from the person's device to Stripe; your servers and the link never see it. Mint one each time you need it: it opens once and lasts 15 minutes.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardLinkRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A card link.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardLink"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: `purpose` is not `card`, `state` is empty, longer than 512 characters (or 1536 once percent-encoded) or holds control characters, `returnUrl` is not one of this application's registered return URLs, or `returnUrl` with `state` and `status` added would pass 4000 characters. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`person_not_ready`: the person has not verified their number with your application yet (POST /users/{userId}/verify/start, then /verify); `error.next` names the step.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Card links for this credential this hour, or for this person.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/{userId}": {
      "get": {
        "tags": [
          "Users"
        ],
        "operationId": "getUser",
        "summary": "Read a person",
        "description": "Whether you may build for this person, and whether a card Layout can order with is on their Layout account. Read it after verify to decide whether to send a card link first, and after the card link returns `status=card_added`, since only this answer comes from Layout. Takes your application's secret key, never a build grant.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The person, now.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStatus"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Reads for this person, or for your application, this hour.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The person's account could not be read right now. Retry shortly.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Users"
        ],
        "operationId": "revokeUser",
        "summary": "Disconnect a person from your application",
        "description": "Ends your application's link to this person: every build grant for them stops working at once, and their standing agreement to your application ordering for them ends. Their Layout account, cards and order history stay theirs and are not deleted. Repeating it answers the same. Provisioning the same number again invites them again under the same id, and they verify again.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked, now or earlier.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedUser"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such user for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users/me/profile": {
      "get": {
        "tags": [
          "Users"
        ],
        "operationId": "getMyProfile",
        "summary": "Read the person's food profile",
        "description": "A connected person's token only; a build grant is refused. Their dietary switch and preference notes, which Layout applies to every build.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The profile.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/places": {
      "get": {
        "tags": [
          "Places"
        ],
        "operationId": "searchPlaces",
        "summary": "Search places",
        "description": "Restaurants open right now, by name or kind of food, from what Layout holds, ranked by the person's location when you send it. Send several names at once, or the ids of places you already picked to read their status now. Send only `lat` and `lng` to browse what Layout holds nearby, nearest first, a page at a time with `cursor`; a browse never looks beyond Layout's registry. Read-only: nothing is built or charged.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "What to look for: a name or a kind of food. Up to 3 names separated by commas search each one and answer them as one list, open places first, then nearest first, so a chain app asks for all its chains in one call. Each name draws one place read and answers at most 10 places. Send `query`, `ids`, or only `lat` and `lng` to browse.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "example": "sweetgreen,chipotle,cava"
          },
          {
            "name": "ids",
            "in": "query",
            "required": false,
            "description": "Up to 25 place ids separated by commas, from earlier results: the places you picked, with their status now, in the order you sent them. Read from what Layout holds and never searched for. Each id draws one place read, as GET /places/{placeId} does. Closed places are included. Send `query`, `ids`, or only `lat` and `lng` to browse.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 6400
            },
            "example": "ChIJbloomCoffee,ChIJtacoSpot"
          },
          {
            "name": "near",
            "in": "query",
            "required": false,
            "description": "A place the person named: a city or town. Results come from that place, and most distances are measured from its centre, not from the person. A neighbourhood, landmark or ZIP code is not matched as an area, and the results then carry `localityMatched: false`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "San Francisco, CA"
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Where the person is. Send with `lng`.",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            },
            "example": 37.7793
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "description": "Where the person is. Send with `lat`.",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            },
            "example": -122.4193
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "`closed` also lists places that are shut now or whose hours Layout does not hold, after the open ones, with `opensAt` and `opensAtIso`, from the places Layout already holds only: it never looks beyond them, so a thin answer says so in `searchLimit`. Without it, a search lists only places open now.",
            "schema": {
              "type": "string",
              "enum": [
                "closed"
              ]
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "`confirmed` lists only places where Layout has found an online ordering route.",
            "schema": {
              "type": "string",
              "enum": [
                "confirmed"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Default 5, at most 25. One name answers at most 10; several names fill up to 25; a browse pages up to 25 at a time. With `ids`, every place you sent is answered and this is ignored.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 25
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "`relevance` (default): one name in Layout's order, best match first; several names open first, then nearest. `distance`: what the search found, nearest first, open or not. A browse is always nearest first.",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "distance"
              ]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "A browse's `nextCursor`, for the next page. Send it with the same `lat`, `lng`, `include` and `ordering` from the same application and person; anything else is refused.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "Places, possibly none. Read `searched` and `emptyBecause` before telling anyone there is nothing there.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter is missing or out of range. The message names it. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake, or this application's daily place reads. The message names the limit.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/places/{placeId}": {
      "get": {
        "tags": [
          "Places"
        ],
        "operationId": "getPlace",
        "summary": "Read one place",
        "description": "One place by the id a places, menu or order result gave you: the place, its dietary, service and good-for facts, and whether it can be ordered from. The same facts the MCP `place_facts` tool reads.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "placeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,255}$"
            },
            "example": "ChIJbloomCoffee"
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Where the person is. Send with `lng`.",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            },
            "example": 37.7793
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "description": "Where the person is. Send with `lat`.",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            },
            "example": -122.4193
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The place.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceDetail"
                }
              }
            }
          },
          "400": {
            "description": "A parameter is out of range. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Layout holds no place with that id that can be shown.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake, or this application's daily place reads.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/menus": {
      "post": {
        "tags": [
          "Menus"
        ],
        "operationId": "readMenu",
        "summary": "Read a menu",
        "description": "The restaurant's menu, read from its own site: a whole menu Layout read within the last 30 days when it holds one (`readAt` says when), else a live read. The same read the MCP `menu` tool runs. A first read takes up to a minute, so this answers 202 `reading` with a `menuId` when it is not done; poll GET /menus/{menuId}. In sandbox it answers only with the menu Layout holds, never a live read, and that is the menu a sandbox cart there is priced from. Read-only: nothing is built or charged to the person.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MenuRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An answer: a menu, its sections, a labeled knowledge answer, or why there is none.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuResult"
                }
              }
            }
          },
          "202": {
            "description": "The read is in flight. Poll GET /menus/{menuId}.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              },
              "Retry-After": {
                "description": "Seconds until the next poll is worth making.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuResult"
                }
              }
            }
          },
          "400": {
            "description": "The body is invalid. The message names the field. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No place with that placeId.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`menu_not_held`, sandbox only: Layout holds no menu for this restaurant. Pick a place from a sandbox places search. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "This menu was read moments ago, a per-minute brake, or a daily allowance of live menu reads (the person's, Layout's, or your application's). The message names which.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/menus/{menuId}": {
      "get": {
        "tags": [
          "Menus"
        ],
        "operationId": "getMenu",
        "summary": "Poll a menu read",
        "description": "Come back for a read POST /menus started. Free: it never starts a read and never draws on an allowance.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "menuId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^mnu_[A-Za-z0-9_-]{16,4092}$"
            },
            "example": "mnu_Q2hJSmJsb29tQ29mZmVl"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The read finished.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuResult"
                }
              }
            }
          },
          "202": {
            "description": "Still reading.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds until the next poll is worth making.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuResult"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such read for this application and person, or it is no longer held. Start a new one with POST /menus.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Polling faster than every few seconds, or the per-credential brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The read could not be checked right now. It is not lost: poll again after Retry-After.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "Retry-After": {
                "description": "Seconds until the next poll is worth making.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/images/items": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "findItemImage",
        "summary": "Get a menu item's photo",
        "description": "The photo a restaurant published of one menu item. The same lookup the MCP `item_photo` tool runs. A photo Layout already holds answers at once and draws no allowance. Otherwise Layout reads the restaurant's own site, answering 200 when the photo turns up within about 12 seconds and 202 `finding` with an `imageId` when it does not; poll GET /images/items/{imageId}. Layout stops looking 35 seconds after the request. Read-only: nothing is built or charged to the person.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ItemImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An answer: the photo, or why there is none.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemImageResult"
                }
              }
            }
          },
          "202": {
            "description": "Still finding it. Poll GET /images/items/{imageId}.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              },
              "Retry-After": {
                "description": "Seconds until the next poll is worth making.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemImageResult"
                }
              }
            }
          },
          "400": {
            "description": "The body is invalid. The message names the field. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No place with that placeId.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake, or a daily allowance of image searches (the person's, Layout's, or your application's). The message names which. Photos Layout already holds never count.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/images/items/{imageId}": {
      "get": {
        "tags": [
          "Images"
        ],
        "operationId": "getItemImage",
        "summary": "Poll for a menu item's photo",
        "description": "Come back for a photo POST /images/items is still finding. Free: it never starts a search and never draws on an allowance. After `giveUpAt` it answers `no_photo` with reason `not_found_in_time`.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "imageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^img_[A-Za-z0-9_-]{16,2048}$"
            },
            "example": "img_Q2hJSmJsb29tQ29mZmVl"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The photo, or the final answer.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemImageResult"
                }
              }
            }
          },
          "202": {
            "description": "Still finding it.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds until the next poll is worth making.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemImageResult"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such search for this application and person, or it is no longer held. Start a new one with POST /images/items.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Polling faster than every couple of seconds, or the per-credential brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The search could not be checked right now. Poll again after Retry-After.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "Retry-After": {
                "description": "Seconds until the next poll is worth making.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts": {
      "post": {
        "tags": [
          "Carts"
        ],
        "operationId": "createCart",
        "summary": "Build a cart",
        "description": "In production, starts a build on the restaurant's own site and answers at once. In sandbox, builds the cart from the restaurant's menu as Layout holds it, with no browser, and takes about as long. Poll GET /carts/{cartId}. Nothing is charged: a cart is built and unpaid until it is confirmed. `simulate`, `latency` and `engine` are sandbox only; production answers `invalid_request` to any of them.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCartRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The build started, or this key already started it.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartAccepted"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: a field is missing or malformed. The message names it. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_conflict`: the key was used for another cart. `in_progress`: the same request is still starting. `store_ambiguous`: pick one of `candidates` and send its placeId. `store_not_found`: no orderable store matched; when Layout found stores nearby with similar names they are in `candidates`, and the person must pick one before you send its placeId. `store_mismatch`: `placeId` and `restaurantName` name different stores; `error.store` is the store the placeId names, with `candidates` matching the name when Layout could find them. Nothing was built: ask the person which store they mean. `menu_not_held`: sandbox only; Layout does not hold this restaurant's menu, so no sandbox cart can be built there. Pick a place from a sandbox places search, which lists only restaurants whose menu Layout holds. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`build_limit`: a daily build budget is spent; the message names which. `rate_limited`: a per-minute brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts/{cartId}": {
      "get": {
        "tags": [
          "Carts"
        ],
        "operationId": "getCart",
        "summary": "Read a cart",
        "description": "The cart as Layout holds it. `totalMinor` is the only total, read from the same order Layout's price lock checks; confirm sends it back unchanged.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "cartId",
            "in": "path",
            "required": true,
            "description": "The `crt_` id.",
            "schema": {
              "type": "string",
              "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
            },
            "example": "crt_0d928d04f1iQbL1AV4iXSKw2wabMk_B-"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The cart.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such cart for this application and person. Another application's cart is a 404 too.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts/{cartId}/answer": {
      "post": {
        "tags": [
          "Carts"
        ],
        "operationId": "answerCart",
        "summary": "Answer a cart's question",
        "description": "Builds the cart again with the person's answer. The answer is a new cart: poll the id this returns.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "cartId",
            "in": "path",
            "required": true,
            "description": "The `crt_` id.",
            "schema": {
              "type": "string",
              "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
            },
            "example": "crt_0d928d04f1iQbL1AV4iXSKw2wabMk_B-"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnswerCartRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The new build started.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartAccepted"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: send exactly one of choices or acceptPickupTime. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such cart for this application and person. Another application's cart is a 404 too.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`answer_not_needed`: the cart is not waiting on that answer, or it was canceled, or it was already answered with another idempotencyKey, when `replacedBy` names the cart that answer started. `idempotency_conflict` / `in_progress` as on POST /carts. `store_ambiguous` / `store_not_found` / `store_mismatch` when the rebuild cannot resolve the store. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`build_limit`: a daily build budget is spent. `rate_limited`: a per-minute brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts/{cartId}/fulfillment": {
      "post": {
        "tags": [
          "Carts"
        ],
        "operationId": "setCartFulfillment",
        "summary": "Choose pickup or delivery",
        "description": "Changes a ready cart to pickup or delivery, its address, or the driver's tip, and answers with the cart at its new total. Delivery is priced live; when it cannot happen, the cart stays a pickup and `fulfillment.deliveryUnavailable` says why. Nothing is charged.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "cartId",
            "in": "path",
            "required": true,
            "description": "The `crt_` id.",
            "schema": {
              "type": "string",
              "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
            },
            "example": "crt_0d928d04f1iQbL1AV4iXSKw2wabMk_B-"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetFulfillmentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The cart at its new total.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: send fulfillment, tip, or both. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such cart for this application and person. Another application's cart is a 404 too.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`cart_not_ready`: only a ready cart can change. `not_delivery`: a tip needs a delivery cart. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts/{cartId}/confirm": {
      "post": {
        "tags": [
          "Carts"
        ],
        "operationId": "confirmCart",
        "summary": "Confirm a cart",
        "description": "Sends the order to be placed and answers `placing`, never `placed`: read GET /orders/{orderId} for the outcome. On a connected person's token, a live confirm needs the 6-digit code Layout texts the person only when the total is over Layout's amount limit for codes (which can change), Layout's risk checks ask for one, or a code is already out for this cart; otherwise one call places it. A live build grant meets the same rules once the person has connected your application, since connecting is their agreement that it places orders for them; for a person who connected before that, the first order's code says so and agrees to it. When it is required the first call texts the person Layout's code, which names the total, the store and the card, and answers `code_required` (when a code texted for this cart in the last 10 minutes is still good, nothing new is texted and you ask the person for that one); you send the same request again with the `code` the person gives you. Layout texts at most four codes per cart. In sandbox the order is simulated and needs no code, except at `test_place_code`, whose code is `000000` and is never texted. `placing` means the confirm was accepted: follow the order, which can still end `failed` without reaching the restaurant.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "cartId",
            "in": "path",
            "required": true,
            "description": "The `crt_` id.",
            "schema": {
              "type": "string",
              "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
            },
            "example": "crt_0d928d04f1iQbL1AV4iXSKw2wabMk_B-"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmCartRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Placing.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderPlacing"
                }
              }
            }
          },
          "400": {
            "description": "`code_required`: ask the person for the code Layout texted and send the same request with it. `code_invalid` / `code_expired`: the code did not match, or is no longer valid (used, expired, replaced, or issued for another total). `invalid_request`: a malformed body, or `expectedTotalMinor` is the restaurant's total without Layout's fee. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "`card_declined`: the person's card was declined. Nothing was placed.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`risk_denied`: Layout will not place this order. `build_only`: the person cannot confirm through Layout yet; `error.next.step` names what is missing (`verify_required`: read back a verify code, which makes or joins their account; `connect_required`: approve a connect link because the person signs in to Layout on this number themselves; `phone_required`: verify their number; `card_required`: add a card; `sign_up_required` and `link_expired` are no longer sent), and `error.next.url`, when present, is the Layout page where the person does it. Otherwise: The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such cart for this application and person. Another application's cart is a 404 too.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`price_changed`: the total moved; read the cart again and show the person the new total. `over_daily_cap`: over the person's daily limit. `cart_not_ready` / `cart_closed`: still building, or no longer confirmable (a canceled, `canceling` or `expired` cart is `cart_closed`). `approval_required`: the person must approve paying through Layout first. `over_order_limit` / `not_placed`: not placed. `idempotency_conflict` / `in_progress`: the key was used for another confirm, or one is running. `texts_blocked`: the person's number replied STOP to Layout, so no code can be texted; they reply START to the number Layout texts from, then you confirm again. `already_confirmed`: the cart was already confirmed, by the person replying YES to Layout's text, in the Layout app, or by another of your requests; nothing was confirmed or charged again. `error.order` is the order and its state now (`placing`, `placed`, `unconfirmed` or `refunded`), with `confirmedVia` when Layout knows where; read GET /orders/{orderId} and do not confirm or build it again. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`code_attempts_exceeded`: too many wrong codes. `rate_limited`: too many codes in a row, the cart's code limit, or the application's daily code limit.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal`: the outcome is not known. Read the order before doing anything else, and do not build it again until it reports a final state.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "`send_failed`: on a live build grant, the code could not be texted. Nothing was confirmed or charged. Retry the same request shortly.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`unavailable`: a check could not run. Nothing was confirmed or charged. Retry the same request.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts/{cartId}/confirm/resend-code": {
      "post": {
        "tags": [
          "Carts"
        ],
        "operationId": "resendCartCode",
        "summary": "Text the confirmation code again",
        "description": "Texts the person a fresh code through the confirm's own check, which replaces any code already out for this cart. A cart that needs no code, and every sandbox cart except one at `test_place_code`, gets `code_not_needed`; at `test_place_code` nothing is texted and the code is `000000`. On a live build grant, a resend texts a code whenever the confirm would ask for one, which includes while the person has not yet agreed to your application ordering for them.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "cartId",
            "in": "path",
            "required": true,
            "description": "The `crt_` id.",
            "schema": {
              "type": "string",
              "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
            },
            "example": "crt_0d928d04f1iQbL1AV4iXSKw2wabMk_B-"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "responses": {
          "200": {
            "description": "A fresh code was texted to the person. At the sandbox test_place_code nothing is texted; the code is 000000.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CodeSent"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`risk_denied`: Layout will not place this order. `build_only`: the person cannot confirm through Layout yet; `error.next.step` names what is missing (`verify_required`: read back a verify code, which makes or joins their account; `connect_required`: approve a connect link because the person signs in to Layout on this number themselves; `phone_required`: verify their number; `card_required`: add a card; `sign_up_required` and `link_expired` are no longer sent), and `error.next.url`, when present, is the Layout page where the person does it. Otherwise: The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such cart for this application and person. Another application's cart is a 404 too.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`code_not_needed`: this cart takes no code; confirm it without one. `cart_closed` / `cart_not_ready`: nothing to confirm. `price_changed` / `over_daily_cap`: the confirm would be refused, so no code was sent. `texts_blocked`: the person's number replied STOP to Layout; they reply START to the number Layout texts from, then you resend. `already_confirmed`: the cart was already confirmed; `error.order` is the order and its state now. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: too many codes in a row, the cart's code limit, or the application's daily code limit.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "`send_failed`: the code could not be texted. Nothing was charged. Retry shortly.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/carts/{cartId}/cancel": {
      "post": {
        "tags": [
          "Carts"
        ],
        "operationId": "cancelCart",
        "summary": "Release a cart",
        "description": "Releases this cart and nothing else. A build grant may release only a cart its own application built. A cart still building is accepted with 202 `canceling`: Layout records the cancel, releases the cart the moment the build lands, and never texts the person that it is ready; read it until it is `canceled`. A cart already confirmed is not canceled here: the answer is `cart_closed` with `error.order` naming the order and its state now.",
        "security": [
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "cartId",
            "in": "path",
            "required": true,
            "description": "The `crt_` id.",
            "schema": {
              "type": "string",
              "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
            },
            "example": "crt_0d928d04f1iQbL1AV4iXSKw2wabMk_B-"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "responses": {
          "200": {
            "description": "Released: `canceled`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartAccepted"
                }
              }
            }
          },
          "202": {
            "description": "The cart is still building. The cancel is recorded: `canceling`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartAccepted"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same, except `grant_expired`: a build grant past its expiry, so mint a new one with POST /users/{userId}/grant.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet. `wrong_credential`: a real credential of the wrong kind for this route, such as your application's secret key where a person's build grant or token is needed; the message names the one to send.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such cart for this application and person. Another application's cart is a 404 too.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`cart_closed`: already confirmed, so not canceled; `error.order` is the order and its state now (`placing`, `placed`, `unconfirmed` or `refunded`). `nothing_to_cancel`: nothing to release. `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Credentials or a dependency could not be checked right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "post": {
        "tags": [
          "Orders"
        ],
        "operationId": "createOrder",
        "summary": "Retired",
        "description": "Answers 410 before reading any credential. Build a cart with POST /carts, or over MCP. The code is `use_carts`.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Gone. Build a cart with POST /carts instead.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "listOrders",
        "summary": "List orders",
        "description": "The orders this application caused in this secret's environment, newest first, each in the same shape as GET /orders/{orderId}. A sandbox secret never sees a live order. Draws on the same per-minute ceiling as GET /orders/{orderId}.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "userId",
            "in": "query",
            "required": false,
            "description": "Only this person's orders. A person who is not this application's in this environment is a 404, as on GET /users/{userId}.",
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "`nextCursor` from the previous page. Opaque.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Default 20.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of orders.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrdersPage"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: `limit` or `cursor` is malformed. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The secret was not recognised, or is revoked.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`wrong_credential`: a build grant was sent; this takes the application's secret.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`userId` names no person of this application in this environment.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute ceiling, shared with GET /orders/{orderId}.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders/{orderId}": {
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "getOrder",
        "summary": "Read an order",
        "description": "An application secret reads any order this application caused. A connected person's token reads only that person's orders this application drove, in the same shape. A build grant reads only an order a build grant from this application built for the same person, in the same environment. An order belonging to another application or another person is a 404, never a 403.",
        "security": [
          {
            "appSecret": []
          },
          {
            "personToken": []
          }
        ],
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^ord_[A-Za-z0-9]{1,64}$"
            },
            "example": "ord_7c21e4b9a0d3"
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "The order.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The secret or token was not recognised, or is expired or revoked.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`unauthorized`: the application may not do this. `insufficient_scope`: a token not granted this scope.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such order for this application.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute ceiling.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "operationId": "listEvents",
        "summary": "Poll the event feed",
        "description": "The same events your webhooks receive, oldest first. Read-only: walking it acknowledges nothing. Filters combine.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "`nextCursor` from a previous page. Continues that walk.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "An `event_id` you already handled, or a `nextCursor`: the page starts with the next event after it. Pass the last `event_id` you processed to catch up.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Only events Layout recorded at or after this time.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"
            },
            "example": "2026-10-01T00:00:00Z"
          },
          {
            "name": "order_id",
            "in": "query",
            "required": false,
            "description": "Only this order's events.",
            "schema": {
              "type": "string",
              "pattern": "^ord_[A-Za-z0-9]{1,64}$"
            },
            "example": "ord_7c21e4b9a0d3"
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "description": "Only this person's events, by the `usr_` id the payload carries.",
            "schema": {
              "type": "string",
              "pattern": "^usr_[a-f0-9]{8,32}$"
            },
            "example": "usr_4b8e9a01c2d3"
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "description": "Only this event type.",
            "schema": {
              "type": "string",
              "enum": [
                "order.building",
                "order.carted",
                "order.placing",
                "order.placed",
                "order.failed",
                "order.unconfirmed",
                "order.needs_approval",
                "order.challenge",
                "order.updated",
                "order.refunded"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Default 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of events.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventsPage"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: a filter is malformed, `after` names no event in this feed, or both `cursor` and `after` were sent. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Usage"
        ],
        "operationId": "getUsage",
        "summary": "Limits and usage",
        "description": "Every limit your application meets in this key's environment and what your developer account has spent today against each daily pool. Free to call and spends nothing.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          }
        ],
        "responses": {
          "200": {
            "description": "Your limits and today's usage.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "description": "`unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Application not permitted. Usually production on an unapproved application. `wrong_credential`: a person's build grant was sent where this route takes your application's secret key.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Usage could not be read right now. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sandbox/webhooks/fire": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "operationId": "fireSandboxWebhook",
        "summary": "Fire a test webhook",
        "description": "Sends one signed test event to each enabled endpoint of this application that subscribes to it, through the real delivery pipeline: the sandbox signing secret, the same headers, the delivery log and the retries. The payload carries `test: true`. With `orderId`, the event describes that sandbox order of this application, with its real id and store, and the response's `order` shows what was sent. Sandbox keys only, and nothing is built.",
        "security": [
          {
            "appSecret": []
          }
        ],
        "parameters": [
          {
            "name": "Layout-Version",
            "in": "header",
            "required": false,
            "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
            "schema": {
              "type": "string",
              "enum": [
                "2026-10-01"
              ]
            },
            "example": "2026-10-01"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. Any 1 to 255 visible ASCII characters, unique per real intent. A retry with the same key and the same body gets the stored response for 24 hours, with `Idempotent-Replayed: true`, and is never run twice. The same key with a different body is `409 idempotency_conflict`; while the first request is still running it is `409 in_progress` with `Retry-After`. Only a success is stored: any error releases the key so it can be sent again. A 4xx ran nothing. A 5xx may have run, above all a confirm's 500, so read the resource before sending anything changed.",
            "schema": {
              "type": "string",
              "pattern": "^[\\x21-\\x7e]{1,255}$"
            },
            "example": "4f1d2c8e-7b6a-4e5f-9c3d-2a1b0e9f8d7c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FireWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent. Read each delivery's outcome.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this is the stored response to an earlier request with the same Idempotency-Key. Absent otherwise.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FireWebhookResult"
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid. The message names the field. `unsupported_version`: the Layout-Version header names no version this API answers.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Secret not recognised, malformed, or rotated.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "A live key, or an application not permitted. This endpoint works with a sandbox key only.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No enabled endpoint subscribes to that event, or `orderId` is not one of this application's sandbox orders.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "A per-minute brake, or this developer account's daily test events.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              },
              "RateLimit-Limit": {
                "description": "Requests this credential may make per minute, every endpoint together.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests this credential may make right now.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until `RateLimit-Remaining` next rises. On a 429 it equals Retry-After.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "Retry-After": {
                "description": "Seconds to wait. Absent on a daily ceiling, which resets at midnight UTC.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 9007199254740991
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Layout failed to answer. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Layout or a dependency could not be reached. Retry with backoff.",
            "headers": {
              "X-Request-Id": {
                "description": "Layout's id for this request. Quote it to support.",
                "schema": {
                  "description": "Layout's id for this request. Quote it to support.",
                  "example": "req_3f9c2a7e1b4d8f6a0c5e9b27",
                  "type": "string",
                  "pattern": "^req_[a-f0-9]{24}$"
                }
              },
              "Layout-Version": {
                "description": "The API version that answered.",
                "schema": {
                  "description": "The API version you code against. Optional; without it you get 2026-10-01, the current version. Layout answers with the version it used.",
                  "example": "2026-10-01",
                  "type": "string",
                  "enum": [
                    "2026-10-01"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "appSecret": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your application secret. `sk_test_` for sandbox, `sk_live_` for production. Read from the Authorization header and nowhere else."
      },
      "personToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Acts for one person: an OAuth access token issued for `https://api.layout.link` to a client your application owns, or an `lgb_` build grant. Read from the Authorization header and nowhere else."
      }
    },
    "schemas": {
      "UserId": {
        "example": "usr_4b8e9a01c2d3",
        "type": "string",
        "pattern": "^usr_[a-f0-9]{8,32}$"
      },
      "OrderId": {
        "example": "ord_7c21e4b9a0d3",
        "type": "string",
        "pattern": "^ord_[A-Za-z0-9]{1,64}$"
      },
      "EventUserId": {
        "example": "usr_4b8e9a01c2d3",
        "type": "string",
        "pattern": "^usr_(?:[a-f0-9]{8,32}|test_[0-9a-f]{6,32})$"
      },
      "EventOrderId": {
        "example": "ord_7c21e4b9a0d3",
        "type": "string",
        "pattern": "^ord_(?:[A-Za-z0-9]{1,64}|test_[0-9a-f]{6,64})$"
      },
      "AppId": {
        "example": "lyt_app_3f9c2a7e1b4d8f6a0c5e9b27",
        "type": "string",
        "pattern": "^(?:lyt_app|app)_[0-9a-f]{8,64}$"
      },
      "Environment": {
        "type": "string",
        "enum": [
          "sandbox",
          "live"
        ]
      },
      "PlaceId": {
        "example": "ChIJbloomCoffee",
        "type": "string",
        "pattern": "^[A-Za-z0-9_-]{1,255}$"
      },
      "StoreCandidate": {
        "type": "object",
        "properties": {
          "placeId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "placeId",
          "name",
          "address"
        ]
      },
      "NamedStore": {
        "type": "object",
        "properties": {
          "placeId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "placeId",
          "name",
          "address"
        ]
      },
      "Limit": {
        "type": "object",
        "properties": {
          "name": {
            "description": "What the ceiling counts.",
            "type": "string",
            "enum": [
              "builds",
              "users_provisioned",
              "build_sessions",
              "verification_texts",
              "place_reads",
              "menu_reads",
              "menu_knowledge",
              "image_searches",
              "test_events"
            ]
          },
          "scope": {
            "description": "Whose ceiling it is: one person, one application, your developer account across its applications, or Layout's own across every developer.",
            "type": "string",
            "enum": [
              "person",
              "application",
              "account",
              "platform"
            ]
          },
          "max": {
            "description": "The ceiling, per day, or per rolling hour when `period` is `hour`.",
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "period": {
            "description": "Present only on a rolling hourly ceiling on texts. Absent means the ceiling is per day.",
            "type": "string",
            "const": "hour"
          },
          "resetsAt": {
            "description": "When it resets: the next midnight UTC, or for an hourly ceiling when the oldest text in the hour ages out and room comes back.",
            "example": "2026-10-02T00:00:00Z",
            "type": "string"
          }
        },
        "required": [
          "name",
          "scope",
          "max",
          "resetsAt"
        ]
      },
      "JoinStep": {
        "type": "object",
        "properties": {
          "step": {
            "description": "What the person, or you, must do before this confirm can work. `verify_required`: the person reads back a code from POST /users/{userId}/verify/start, which you send to POST /users/{userId}/verify; their account is then ready. `connect_required`: the person signs in to Layout on this number themselves; send a connect link (POST /users/{userId}/connect). `phone_required`: the person verifies their number in Layout. `card_required`: mint a card link with POST /users/{userId}/links and send them to its `url`. `sign_up_required` and `link_expired` are not sent.",
            "type": "string",
            "enum": [
              "sign_up_required",
              "verify_required",
              "connect_required",
              "link_expired",
              "phone_required",
              "card_required"
            ]
          },
          "url": {
            "description": "Layout's page for the step, on a person's own Layout token only. Absent for a person you provisioned.",
            "example": "https://account.layout.link/billing/card/new",
            "type": "string"
          }
        },
        "required": [
          "step"
        ]
      },
      "ConfirmedVia": {
        "description": "Where the person confirmed it, when Layout knows: `sms`, by replying YES to Layout's cart-ready text; `tracking_link`, on Layout's tracking page. Absent when Layout does not know, which includes the Layout app and any API or MCP confirm.",
        "type": "string",
        "enum": [
          "sms",
          "tracking_link"
        ]
      },
      "CodeReason": {
        "description": "`over_limit`: the total is over Layout's limit for orders without a code. `code_outstanding`: a code was already texted for this cart. `first_order_consent`: on a build grant, the person has not yet agreed to your application ordering for them; the first order's code is that agreement. `risk_check`: Layout's checks asked for one on this order (on `code_required`, and on the cart at the sandbox's `test_place_code`). `unverified`: Layout could not check just now, so it asks for the code.",
        "type": "string",
        "enum": [
          "over_limit",
          "code_outstanding",
          "first_order_consent",
          "risk_check",
          "unverified"
        ]
      },
      "ErrorOrder": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/OrderId"
          },
          "status": {
            "description": "The order's state now, the same value GET /orders/{orderId} reports. `unconfirmed` is not failed: do not build it again.",
            "type": "string",
            "enum": [
              "placing",
              "placed",
              "unconfirmed",
              "refunded",
              "failed"
            ]
          },
          "confirmedVia": {
            "$ref": "#/components/schemas/ConfirmedVia"
          }
        },
        "required": [
          "id",
          "status"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "unauthorized",
                  "forbidden",
                  "insufficient_scope",
                  "confirm_required",
                  "bad_code",
                  "not_found",
                  "method_not_allowed",
                  "already_claimed",
                  "moved_to_mcp",
                  "use_carts",
                  "rate_limited",
                  "internal",
                  "send_failed",
                  "unavailable",
                  "idempotency_conflict",
                  "in_progress",
                  "store_ambiguous",
                  "store_not_found",
                  "store_mismatch",
                  "menu_not_held",
                  "build_limit",
                  "cart_not_ready",
                  "cart_closed",
                  "answer_not_needed",
                  "not_delivery",
                  "nothing_to_cancel",
                  "build_only",
                  "price_changed",
                  "over_daily_cap",
                  "code_required",
                  "code_invalid",
                  "code_expired",
                  "code_attempts_exceeded",
                  "code_not_needed",
                  "risk_denied",
                  "card_declined",
                  "over_order_limit",
                  "not_placed",
                  "approval_required",
                  "texts_blocked",
                  "phone_changed",
                  "already_confirmed",
                  "grant_expired",
                  "unsupported_version",
                  "wrong_credential",
                  "provisioned_to_another_app",
                  "person_not_ready"
                ]
              },
              "message": {
                "description": "One sentence for a developer. Never parse it; switch on `code`.",
                "type": "string"
              },
              "orderId": {
                "description": "The order the error is about, when there is one.",
                "type": "string"
              },
              "candidates": {
                "description": "On `store_ambiguous`: the stores to choose from. On `store_mismatch`, when Layout could look them up cheaply: stores matching `restaurantName` near the person.",
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/StoreCandidate"
                }
              },
              "store": {
                "description": "On `store_mismatch`: the store the placeId names, with its address.",
                "$ref": "#/components/schemas/NamedStore"
              },
              "limit": {
                "description": "On a refusal by a daily ceiling: the ceiling. Absent on a per-minute brake.",
                "$ref": "#/components/schemas/Limit"
              },
              "next": {
                "description": "On `build_only` when the person has not finished joining Layout: the missing step, and where they complete it.",
                "$ref": "#/components/schemas/JoinStep"
              },
              "order": {
                "description": "On `already_confirmed`, and on `cart_closed`: the order, its state now, and where it was confirmed when Layout knows. On a cancel of a cart whose order already ended it reads `failed`.",
                "$ref": "#/components/schemas/ErrorOrder"
              },
              "userMessage": {
                "description": "On `already_confirmed`: one sentence for the person, safe to show as written.",
                "type": "string"
              },
              "codeReason": {
                "description": "On `code_required`: why this confirm needs the code.",
                "$ref": "#/components/schemas/CodeReason"
              },
              "replacedBy": {
                "description": "On `answer_not_needed` for a cart that was already answered: the cart its answer started. Read that one.",
                "type": "string"
              },
              "retryInSeconds": {
                "description": "On a 429 that carries Retry-After: the same wait, in seconds, so a device can say it.",
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991
              },
              "reason": {
                "description": "On a confirm whose `expectedTotalMinor` is the restaurant's total without Layout's service fee: `fee_not_included`. Show the person the cart's `totalMinor` and confirm with that.",
                "type": "string",
                "enum": [
                  "fee_not_included"
                ]
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "CreateUserRequest": {
        "type": "object",
        "properties": {
          "firstName": {
            "description": "Shown to the person on the consent screen.",
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "lastName": {
            "description": "Shown to the person on the consent screen.",
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "phone": {
            "description": "E.164. The person verifies it themselves.",
            "example": "+15005550142",
            "type": "string",
            "pattern": "^\\+[1-9]\\d{6,14}$"
          },
          "email": {
            "description": "Optional and unverified. Kept with the provisioning link; never written to the person's own Layout account, never shown to another partner.",
            "type": "string",
            "maxLength": 254,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "label": {
            "description": "Your own name for this person, shown in the console.",
            "type": "string",
            "maxLength": 120
          },
          "connectDelivery": {
            "description": "For a number the person signs in to Layout on themselves: return the consent link instead of Layout texting it.",
            "type": "string",
            "enum": [
              "developer"
            ]
          }
        },
        "required": [
          "firstName",
          "lastName",
          "phone"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/UserId"
          },
          "status": {
            "example": "provisioned",
            "type": "string"
          },
          "next": {
            "description": "The next step for this person. `verify`: a new number, or one whose only Layout account another application's verify made; a good verify code makes or joins the person's account. `connect`: the person signs in to Layout on this number themselves and you asked to deliver the link; send them to `connect.connectUrl`. `awaiting_user_approval`: the person signs in to Layout on this number themselves, and Layout texted them the approval link. `connected`: already connected, start building.",
            "type": "string",
            "enum": [
              "verify",
              "connect",
              "awaiting_user_approval",
              "connected"
            ]
          },
          "connect": {
            "description": "Present only when `next` is `connect`.",
            "type": "object",
            "properties": {
              "connectUrl": {
                "type": "string",
                "format": "uri"
              },
              "expiresInSec": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "connectUrl",
              "expiresInSec"
            ]
          },
          "awaitingApproval": {
            "description": "Present only when `next` is `awaiting_user_approval`.",
            "type": "object",
            "properties": {
              "phoneHint": {
                "type": "string"
              },
              "expiresInSec": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "expiresInSec"
            ]
          },
          "session": {
            "description": "Carries no token and authenticates nothing. Mint a build grant with POST /users/{userId}/grant.",
            "type": "object",
            "properties": {
              "scope": {
                "type": "string",
                "const": "build"
              },
              "expiresIn": {
                "description": "Seconds the build session lasts.",
                "example": 900,
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "scope",
              "expiresIn"
            ]
          },
          "handoffUrl": {
            "deprecated": true,
            "description": "Deprecated since 2026-10-21 and kept for older integrations. Do not send anyone here: verify the person with POST /users/{userId}/verify/start and POST /users/{userId}/verify, which makes their Layout account.",
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "id",
          "status",
          "next",
          "session",
          "handoffUrl"
        ]
      },
      "VerifyStarted": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "id": {
            "$ref": "#/components/schemas/UserId"
          },
          "phoneHint": {
            "description": "The masked number the code went to.",
            "type": "string"
          },
          "expiresInSec": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "sandbox": {
            "description": "Sandbox texts nobody. The code is always 000000.",
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "ok",
          "id"
        ]
      },
      "VerifyRequest": {
        "type": "object",
        "properties": {
          "code": {
            "description": "The six-digit code the person read back.",
            "example": "246810",
            "type": "string",
            "pattern": "^\\d{6}$"
          }
        },
        "required": [
          "code"
        ]
      },
      "CardStatus": {
        "type": "object",
        "properties": {
          "onFile": {
            "description": "True when the person's Layout account holds a card.",
            "type": "boolean"
          },
          "orderable": {
            "description": "True when Layout can order with the card it would charge. False with no card, when that card's issuer refuses orders like Layout's, or when it cannot be charged yet: mint a card link with POST /users/{userId}/links so the person adds another.",
            "type": "boolean"
          },
          "brand": {
            "description": "The card Layout would charge. Null with no card.",
            "example": "visa",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "last4": {
            "description": "Null with no card.",
            "example": "4242",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "onFile",
          "orderable",
          "brand",
          "last4"
        ]
      },
      "Verified": {
        "type": "object",
        "properties": {
          "id": {
            "example": "usr_4b8e9a01c2d3",
            "description": "The same per-application user id every time this person verifies, so a returning person on a new device is recognised.",
            "$ref": "#/components/schemas/UserId"
          },
          "verified": {
            "description": "The code was right. It says nothing about whether this application may build; read `authorized`.",
            "type": "boolean",
            "const": true
          },
          "authorized": {
            "description": "True when this application may now build for this person. False when the person signs in to Layout on this number themselves: only they can connect it.",
            "type": "boolean"
          },
          "next": {
            "description": "Present when `authorized` is false: get a consent link from POST /users/{userId}/connect.",
            "type": "string",
            "const": "connect"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "provisioned"
            ]
          },
          "claimed": {
            "description": "True once the person has their own Layout account, which a good production verify code makes or joins.",
            "type": "boolean"
          },
          "card": {
            "description": "The person's card, once `authorized` is true, so you know whether to send a card link before building. Null while `authorized` is false. Absent when Layout could not read it just then: read GET /users/{userId}.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/CardStatus"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "verified",
          "authorized"
        ]
      },
      "UserStatus": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/UserId"
          },
          "status": {
            "example": "active",
            "type": "string"
          },
          "authorized": {
            "description": "True when your application may build for this person.",
            "type": "boolean"
          },
          "card": {
            "description": "Null until `authorized` is true. Before that, Layout says nothing about the person's account.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/CardStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "textsBlocked": {
            "description": "True when the person's number replied STOP to Layout, so a confirm that needs an order code answers `texts_blocked` until they reply START. Null until `authorized` is true.",
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "status",
          "authorized",
          "card",
          "textsBlocked"
        ]
      },
      "ConnectRequest": {
        "type": "object",
        "properties": {
          "returnUrl": {
            "description": "https only. Where to send the person after they decide.",
            "type": "string",
            "format": "uri"
          },
          "connectDelivery": {
            "description": "Return the link instead of Layout texting it to the person.",
            "type": "string",
            "enum": [
              "developer"
            ]
          }
        }
      },
      "ConnectLink": {
        "type": "object",
        "properties": {
          "next": {
            "type": "string",
            "enum": [
              "connect",
              "awaiting_user_approval"
            ]
          },
          "connectUrl": {
            "description": "Present when `next` is `connect`. Open it in the person's browser.",
            "type": "string",
            "format": "uri"
          },
          "expiresInSec": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "awaitingApproval": {
            "description": "Present when Layout texted the person the approval link.",
            "type": "object",
            "properties": {
              "phoneHint": {
                "type": "string"
              },
              "expiresInSec": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "expiresInSec"
            ]
          },
          "connected": {
            "description": "Already connected to this person; no link is issued.",
            "type": "boolean",
            "const": true
          },
          "id": {
            "$ref": "#/components/schemas/UserId"
          },
          "status": {
            "type": "string"
          }
        }
      },
      "Grant": {
        "type": "object",
        "properties": {
          "token": {
            "description": "Build-only. A new grant's token is returned exactly once; a refresh returns the same token.",
            "example": "lgb_9f3a2c",
            "type": "string"
          },
          "expiresAt": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "const": "build"
          },
          "refreshed": {
            "description": "Present when this call extended the grant you sent as `refresh`.",
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "token",
          "expiresAt",
          "scope"
        ]
      },
      "GrantRequest": {
        "type": "object",
        "properties": {
          "refresh": {
            "description": "This person's current, unexpired grant. Extends that same token by 15 minutes, up to 24 hours from when it was minted, and draws no build-session allowance. Omit it, or send null, to mint a new grant.",
            "example": "lgb_9f3a2c",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "CardLinkRequest": {
        "type": "object",
        "properties": {
          "purpose": {
            "description": "What the page does. `card` adds a card to the person's Layout account. On an account already holding all the cards it can, it replaces a card your own card links added, or, on an account nobody signs in to Layout with, the default card. The page asks the person before it replaces one. When there is no card it may replace, the page tells the person their account is full, and going back returns `status=canceled`.",
            "type": "string",
            "const": "card"
          },
          "returnUrl": {
            "description": "Where the page sends the person when they finish or go back: exactly one of the return URLs registered for this application in the console. An https universal link or your app's own scheme; localhost only with a sandbox key.",
            "example": "slopbowls://layout/card",
            "type": "string"
          },
          "state": {
            "description": "Returned to you unchanged on the return URL as `state`, so you can match the person who comes back. At most 512 characters, and at most 1536 once percent-encoded, so the return URL with `state` and `status` added always fits in 4000 characters.",
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          }
        },
        "required": [
          "purpose"
        ]
      },
      "CardLink": {
        "type": "object",
        "properties": {
          "url": {
            "description": "Send the person here. Single use, no Layout sign-in, branded with your approved application's name and logo. On finishing it returns to `returnUrl` with `status=card_added`, or `status=canceled` when they go back, plus your `state`.",
            "example": "https://layout.link/h/3QpX9cTn1yVb8sWm2kLq7rZa5dEf0gHj4uIo6pNs8tY",
            "type": "string",
            "format": "uri"
          },
          "expiresAt": {
            "description": "When the link stops opening, 15 minutes after it was minted.",
            "type": "string"
          },
          "purpose": {
            "type": "string",
            "const": "card"
          }
        },
        "required": [
          "url",
          "expiresAt",
          "purpose"
        ]
      },
      "RevokedUser": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/UserId"
          },
          "status": {
            "type": "string",
            "const": "revoked"
          }
        },
        "required": [
          "id",
          "status"
        ]
      },
      "OrderState": {
        "type": "string",
        "enum": [
          "building",
          "carted",
          "placing",
          "placed",
          "failed",
          "unconfirmed",
          "refunded"
        ]
      },
      "DeliveryStatus": {
        "type": "string",
        "enum": [
          "finding_courier",
          "heading_to_store",
          "at_store",
          "on_the_way",
          "arriving",
          "delivered",
          "failed"
        ]
      },
      "Fulfillment": {
        "type": "object",
        "properties": {
          "type": {
            "description": "How the person gets the order. A delivery that never got a driver becomes `pickup`, with `changed_from` set; tell the person to collect it.",
            "type": "string",
            "enum": [
              "pickup",
              "delivery"
            ]
          },
          "name": {
            "description": "The name the store has the order under, as its own confirmation stated it. What the person says at the counter.",
            "example": "Cole",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "address": {
            "description": "Where the person collects it. For pickup, the same as `store_address`. For delivery, the street line it is going to.",
            "example": "709 Cirby Way, Roseville, CA 95678",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "ready_text": {
            "description": "The pickup time word for word, the same as `ready_eta`. Show it as written; it is not a timestamp.",
            "example": "Ready by 6:15 PM",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "merchant_order_number": {
            "description": "The store's own number for the order, not Layout's id.",
            "example": "71711896",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "instructions": {
            "description": "The store's own pickup instructions, word for word.",
            "example": "Pick up at the mobile order counter",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "description": "Delivery only: where the driver is. Absent for pickup.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeliveryStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "eta": {
            "description": "Delivery only: when it should arrive, ISO 8601, once known.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "courier": {
            "description": "Delivery only: the driver, while one is assigned. Cleared once the delivery ends.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "first_name": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "vehicle": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "first_name",
                  "vehicle"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "proof_photo_url": {
            "description": "Delivery only: the driver's photo of the order at the door, once delivered and left there. Show it as proof of delivery.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "failure_reason": {
            "description": "Delivery only: why the delivery could not be completed, in words you can show the person. Set when `status` is `failed`.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "changed_from": {
            "description": "Set when a delivery became a pickup because no driver could be booked.",
            "anyOf": [
              {
                "type": "string",
                "const": "delivery"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "type",
          "name",
          "address",
          "ready_text",
          "merchant_order_number",
          "instructions"
        ]
      },
      "OrderLine": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "unit_price_minor": {
            "description": "Per item, when the store's cart priced it.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "modifiers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name",
          "quantity",
          "unit_price_minor",
          "modifiers"
        ]
      },
      "OrderAmounts": {
        "type": "object",
        "properties": {
          "subtotal_minor": {
            "description": "The store's own subtotal, when it stated one.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "tax_minor": {
            "description": "The store's own tax, when it stated it.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "merchant_total_minor": {
            "description": "The store's total, the same as `total_minor`.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "service_fee_minor": {
            "description": "Layout's service fee.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "service_fee_waived": {
            "description": "True when the person's plan waives the fee: it is shown but not charged.",
            "type": "boolean"
          },
          "credit_minor": {
            "description": "Layout credit taken off the charge.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "courier_fee_minor": {
            "description": "The delivery fee charged, at cost. 0 for pickup, and 0 when no driver delivered.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "tip_minor": {
            "description": "The driver's tip charged, all of it to the driver. 0 for pickup, and 0 when no driver delivered.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "charged_minor": {
            "description": "What the person's card was charged for the placed order: the store's total, plus the fee unless waived, plus any delivery fee and tip, less credit. Null until `state` is `placed`, and on a simulated order. A later refund is not netted here.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "subtotal_minor",
          "tax_minor",
          "merchant_total_minor",
          "service_fee_minor",
          "service_fee_waived",
          "credit_minor",
          "courier_fee_minor",
          "tip_minor",
          "charged_minor"
        ]
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/OrderId"
          },
          "state": {
            "$ref": "#/components/schemas/OrderState"
          },
          "store": {
            "example": "Layout test kitchen",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "store_address": {
            "description": "The address of that store, when Layout knows it.",
            "example": "1 Sandbox Way, San Francisco, CA 94107",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "items": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "total_minor": {
            "description": "Minor units. 2140 is $21.40.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "example": "usd",
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "placed_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "ready_eta": {
            "description": "The pickup time as the store stated it, word for word, when the store states one. Layout reads it from the store's confirmation screen and its email, so it can arrive after `placed`, with an `order.updated` event. Null until then, and null for good when the store never states a time; the person then goes by the store's own confirmation. Show it as written; it is not a timestamp.",
            "example": "Ready by 6:15 PM",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "ready_at": {
            "description": "The same pickup time as an instant, ISO 8601, only when Layout could place `ready_eta` on the store's clock. Null when the store's words are not a time Layout can pin down. Show `ready_eta`; use this to schedule or sort.",
            "example": "2026-10-01T01:15:00.000Z",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "refunded_minor": {
            "description": "Minor units refunded on this order so far, across every refund. 0 when none. `state` does not change when an order is refunded; `order.refunded` comes with each refund.",
            "example": 0,
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "failure_code": {
            "description": "A stable machine code, never prose. Read it only when `state` is `failed` or `unconfirmed`: an order still `placing` can carry one before it settles, so switch on `state` first. One of `LOGIN_REQUIRED`, `SITE_BLOCKED`, `RATE_LIMITED`, `ITEM_UNAVAILABLE`, `SITE_ERROR`, `STORE_CLOSED`, `PICKUP_TIME_EXPIRED`, `CHECKOUT_NOT_FOUND`, `ORDERING_PAGE_NOT_FOUND`, `CLOSED_NEXT_DAY`, `MARKETPLACE_ONLY`, `APP_ONLY_ORDERING`, `ACCOUNT_VERIFICATION_REQUIRED`, `CART_DRIFTED`, `CARD_DECLINED`, `CARD_REMOVED`, `PAYMENT_REJECTED`, `OUR_TIMEOUT`, `OUR_ERROR`, `UNCONFIRMED`, `UNKNOWN`, `USER_CANCELED`, `STAFF_STOPPED`, `SESSION_EXPIRED`, `SUPERSEDED_BY_CHANGE`, `CART_EXPIRED`. Treat any value you do not recognise as `UNKNOWN`.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "simulated": {
            "description": "Present and true on a sandbox order that was simulated. Absent on every real order.",
            "type": "boolean",
            "const": true
          },
          "challenge": {
            "description": "Present while `state` is `placing` and the payment waits on the person approving it: tell them to open the link Layout texted them. Absent otherwise. `order.challenge` says the same as a webhook.",
            "type": "object",
            "properties": {
              "sms_sent": {
                "description": "True when Layout texted the person the approval link. False at the sandbox `test_place_challenge`, which texts nobody.",
                "type": "boolean"
              }
            },
            "required": [
              "sms_sent"
            ]
          },
          "fulfillment": {
            "$ref": "#/components/schemas/Fulfillment"
          },
          "lines": {
            "description": "What was ordered, as the cart was built. Layout's derived tax-and-fees line is not a line.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLine"
            }
          },
          "amounts": {
            "$ref": "#/components/schemas/OrderAmounts"
          }
        },
        "required": [
          "id",
          "state",
          "store",
          "store_address",
          "items",
          "total_minor",
          "currency",
          "created_at",
          "placed_at",
          "ready_eta",
          "ready_at",
          "refunded_minor",
          "failure_code",
          "fulfillment",
          "lines",
          "amounts"
        ]
      },
      "OrdersPage": {
        "type": "object",
        "properties": {
          "orders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Order"
            }
          },
          "nextCursor": {
            "description": "Null on the last page.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "orders",
          "nextCursor"
        ]
      },
      "EventId": {
        "example": "evt_87228f5aa7b9_placed",
        "type": "string",
        "pattern": "^evt_[A-Za-z0-9]{1,64}_[a-z-]{1,20}(?:_(?:[2-9]|[1-9][0-9]{1,3}))?$"
      },
      "Event": {
        "type": "object",
        "properties": {
          "event": {
            "description": "`order.updated` comes after `order.placed` each time more pickup details arrive (the name the order is under, the ready time, the store's own order number, instructions). Layout reads them from several places, such as the store's confirmation screen and its email, so they can arrive in more than one wave, minutes apart. On a delivery order it also comes when the driver picks the food up, when it is delivered, and when delivery could not happen (the order then reads as a pickup with `changed_from: \"delivery\"`). Handle every one. Its `state` stays `placed`, and its `order` carries `ready_eta`, `ready_at` and `fulfillment` as GET /orders/{orderId} returns them when the event is written. `order.refunded` comes with each refund Layout issues on an order, one event per refund; its `state` is the order's state, unchanged, and its `order` carries `refunded_minor` and `method` for that one refund.",
            "type": "string",
            "enum": [
              "order.building",
              "order.carted",
              "order.placing",
              "order.placed",
              "order.failed",
              "order.unconfirmed",
              "order.needs_approval",
              "order.challenge",
              "order.updated",
              "order.refunded"
            ]
          },
          "event_id": {
            "$ref": "#/components/schemas/EventId"
          },
          "delivery_id": {
            "description": "This delivery. A retry of it keeps the id; a replay gets a new one.",
            "example": "dl_351eacf74201",
            "type": "string"
          },
          "test": {
            "description": "A test delivery: the console's Send test event, POST /v1/sandbox/webhooks/fire, or `layout trigger`.",
            "type": "boolean",
            "const": true
          },
          "order": {
            "description": "No item names or modifiers: read GET /orders/{orderId} for the full order. `order.updated` also carries the pickup details.",
            "type": "object",
            "properties": {
              "id": {
                "$ref": "#/components/schemas/EventOrderId"
              },
              "state": {
                "$ref": "#/components/schemas/OrderState"
              },
              "store": {
                "description": "The store's name.",
                "example": "Layout test kitchen",
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "store_address": {
                "description": "The store's address, when Layout knows it. Null when `store` is null. Absent only on events written before this field existed.",
                "example": "1 Sandbox Way, San Francisco, CA 94107",
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "items": {
                "description": "How many items the order holds. The items themselves are not in the payload.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "total_minor": {
                "description": "Minor units. 2140 is $21.40. Null before the cart is priced.",
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "currency": {
                "example": "usd",
                "type": "string"
              },
              "simulated": {
                "description": "Present and true on a sandbox order that was simulated. Absent on every real order.",
                "type": "boolean",
                "const": true
              },
              "failure_code": {
                "description": "On `order.failed` only: the same stable machine code `GET /orders/{orderId}` returns, or null when Layout recorded none.",
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ready_eta": {
                "description": "On `order.updated` only: the pickup time as `GET /orders/{orderId}` returns it when the event is written. Absent on an event written before this field existed, or when Layout could not read the order then.",
                "example": "Ready by 6:15 PM",
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ready_at": {
                "description": "On `order.updated` only: the pickup time as an instant, as `GET /orders/{orderId}` returns it when the event is written. Null when the store's words are not a time Layout can pin down.",
                "example": "2026-10-01T01:15:00.000Z",
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "refunded_minor": {
                "description": "On `order.refunded` only: the amount of this one refund, in minor units. GET /orders/{orderId} `refunded_minor` is the total so far.",
                "example": 1234,
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "method": {
                "description": "On `order.refunded` only: `credit` is Layout credit on the person's account; `card` goes back to their card.",
                "type": "string",
                "enum": [
                  "card",
                  "credit"
                ]
              },
              "fulfillment": {
                "description": "On `order.updated` only: how the person gets the order, as `GET /orders/{orderId}` returns it when the event is written. Absent when `ready_eta` is.",
                "$ref": "#/components/schemas/Fulfillment"
              }
            },
            "required": [
              "id",
              "state",
              "store",
              "items",
              "total_minor",
              "currency"
            ]
          },
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "$ref": "#/components/schemas/EventUserId"
              }
            },
            "required": [
              "id"
            ]
          },
          "occurred_at": {
            "description": "When the order changed. Use it, not `sent_at`, to order events.",
            "example": "2026-10-01T17:01:05Z",
            "type": "string"
          },
          "sent_at": {
            "description": "When Layout wrote this delivery.",
            "example": "2026-09-13T10:14:03Z",
            "type": "string"
          }
        },
        "required": [
          "event",
          "event_id",
          "delivery_id",
          "order",
          "user",
          "occurred_at",
          "sent_at"
        ]
      },
      "EventsPage": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          },
          "nextCursor": {
            "description": "Null at the end. To resume later, pass the last `event_id` as `after`.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "events",
          "nextCursor"
        ]
      },
      "Whoami": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "const": "app"
              },
              "app": {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/AppId"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "environment": {
                "$ref": "#/components/schemas/Environment"
              },
              "approvalStatus": {
                "type": "string",
                "enum": [
                  "pending",
                  "approved",
                  "denied",
                  "suspended"
                ]
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "kind",
              "app",
              "environment",
              "approvalStatus",
              "scopes"
            ]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "const": "user"
              },
              "app": {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/AppId"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "environment": {
                "$ref": "#/components/schemas/Environment"
              },
              "user": {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/UserId"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "kind",
              "app",
              "environment",
              "user",
              "scopes"
            ]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "const": "grant"
              },
              "app": {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/AppId"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "environment": {
                "$ref": "#/components/schemas/Environment"
              },
              "user": {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/UserId"
                  }
                },
                "required": [
                  "id"
                ]
              },
              "scopes": {
                "description": "`build`: build, read and cancel this application's carts for the person. `confirm`: confirm them, with the person's order code whenever Layout asks for one.",
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "build",
                    "confirm"
                  ]
                }
              },
              "expiresAt": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "app",
              "environment",
              "user",
              "scopes",
              "expiresAt"
            ]
          }
        ]
      },
      "Place": {
        "type": "object",
        "properties": {
          "placeId": {
            "$ref": "#/components/schemas/PlaceId"
          },
          "slug": {
            "description": "The public storefront path on layout.link.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "city": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "region": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "cuisine": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "rating": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "priceLevel": {
            "description": "1 (inexpensive) to 4 (very expensive). Null: not known.",
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "website": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "openNow": {
            "description": "Prefer `openStatus`: null here means not known, never closed.",
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ]
          },
          "openStatus": {
            "description": "At the store's own clock. `unknown`: Layout holds no hours.",
            "type": "string",
            "enum": [
              "open",
              "closed",
              "unknown"
            ]
          },
          "ordering": {
            "description": "`confirmed`: Layout found an online ordering route. `unconfirmed`: not decided yet. `unavailable`: Layout looked and there is none.",
            "type": "string",
            "enum": [
              "confirmed",
              "unconfirmed",
              "unavailable"
            ]
          },
          "closesAt": {
            "description": "Store-local closing time when open.",
            "example": "5:00 PM",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "opensAt": {
            "description": "Store-local next opening when closed.",
            "example": "Monday 7:00 AM",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "closingSoon": {
            "description": "Open, and closing within 45 minutes.",
            "type": "boolean"
          },
          "closesAtIso": {
            "description": "When it closes, as an instant, when open. Compare it to your own clock rather than trusting `closingSoon` on a cached row.",
            "example": "2026-10-22T00:00:00.000Z",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "opensAtIso": {
            "description": "When it next opens, as an instant, when closed. Sort on this, not on `opensAt`.",
            "example": "2026-10-22T14:00:00.000Z",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "lat": {
            "description": "Where the store is.",
            "example": 37.7793,
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "lng": {
            "description": "Where the store is.",
            "example": -122.4193,
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "distanceKm": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "distanceMi": {
            "description": "One decimal. Usually from the centre of `near` when it is sent and Layout can place it, else from `lat`/`lng`. Check `localityMatched`. Null without a location.",
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "photoUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "cuisines": {
            "description": "Finer cuisine words than `cuisine`, from the kinds of place Google lists it as and its `cuisine`, sorted. Empty when Layout holds none. Each is one of: american, bakery, bbq, bowls, breakfast, bubble_tea, burger, cafe, chicken, chinese, dessert, fast_food, greek, indian, italian, japanese, juice, korean, mediterranean, mexican, middle_eastern, noodles, pizza, poke, ramen, salad, sandwich, seafood, steak, sushi, thai, vegan, vegetarian, vietnamese. New words may be added.",
            "example": [
              "bowls",
              "mediterranean"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "matchedOn": {
            "description": "On a `query` search only: what the query matched. `name`: every word that matched the name is a whole word of it. `name_partial`: a word only begins or sits inside a word of the name, so `cava` on Cavaña. `cuisine`: the cuisine. `kind`: the kind of place Google lists it as. Null: found by a search beyond Layout's registry, which cannot say.",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "name",
                  "name_partial",
                  "cuisine",
                  "kind"
                ]
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "placeId",
          "slug",
          "name",
          "address",
          "city",
          "region",
          "cuisine",
          "rating",
          "priceLevel",
          "website",
          "openNow",
          "openStatus",
          "ordering",
          "closesAt",
          "opensAt",
          "closingSoon",
          "closesAtIso",
          "opensAtIso",
          "lat",
          "lng",
          "distanceKm",
          "distanceMi",
          "photoUrl",
          "cuisines"
        ]
      },
      "PlaceList": {
        "type": "object",
        "properties": {
          "places": {
            "description": "Places open right now. With several names, nearest first. With `include=closed`, the places that are shut or whose hours Layout does not hold follow the open ones. With `ids`, every place you sent that Layout holds, open or not, in your order; with `ordering=confirmed` as well, only the confirmed ones.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Place"
            }
          },
          "nextCursor": {
            "description": "On a browse: send it as `cursor` for the next page, nearest first from where this one ended. Null when there is no further page. Each page draws one place read.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "missing": {
            "description": "With `ids`: the ids Layout holds no place for, or no longer shows. Present only when there is one.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlaceId"
            }
          },
          "stillChecking": {
            "description": "Layout is still checking whether more places there take online orders. Ask again in a minute.",
            "type": "boolean",
            "const": true
          },
          "stillCheckingCount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "searched": {
            "description": "False when Layout did not look this time, so an empty list says nothing about the area.",
            "type": "boolean"
          },
          "localityMatched": {
            "description": "False when Layout could not place `near`: the rows are real but not where the person asked.",
            "type": "boolean"
          },
          "emptyBecause": {
            "description": "Why `places` is empty, when it is: everything there is shut, Layout did not look this time, the query named nothing to look for, (`no_match`) Layout looked and holds no open place matching the query, (`none_confirmed`, with `ordering=confirmed`) Layout holds matching places but has confirmed online ordering at none of them, or (`no_held_menu`, sandbox only) Layout holds matching places but holds the menu of none of them. `query` matches a restaurant's name, the kind of food it serves, or a common drink: a latte finds the coffee and tea shops that pour it.",
            "type": "string",
            "enum": [
              "all_closed",
              "not_searched",
              "nothing_to_search",
              "no_match",
              "none_confirmed",
              "no_held_menu"
            ]
          },
          "searchLimit": {
            "description": "Sent with `searched: false` when a limit, not the area, is why Layout did not look further.",
            "type": "object",
            "properties": {
              "pool": {
                "description": "`registry_only`: sandbox and applications not approved for live search only what Layout already holds. `approved`: an approved live application's pool of searches beyond it.",
                "type": "string",
                "enum": [
                  "registry_only",
                  "approved"
                ]
              },
              "scope": {
                "description": "Whose daily limit stopped the search: your developer account's, or the pool's across every developer. Null for `registry_only`.",
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "developer",
                      "platform"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "perDay": {
                "description": "The limit that applied, per day. 0 for `registry_only`.",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "pool",
              "scope",
              "perDay",
              "message"
            ]
          }
        },
        "required": [
          "places",
          "searched",
          "localityMatched"
        ]
      },
      "PlaceFacts": {
        "type": "object",
        "properties": {
          "dietary": {
            "type": "object",
            "properties": {
              "vegetarian": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "breakfast": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "lunch": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "dinner": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "brunch": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "vegetarian",
              "breakfast",
              "lunch",
              "dinner",
              "brunch"
            ]
          },
          "service": {
            "type": "object",
            "properties": {
              "dineIn": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "takeout": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "delivery": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "curbside": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "reservable": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "dineIn",
              "takeout",
              "delivery",
              "curbside",
              "reservable"
            ]
          },
          "goodFor": {
            "type": "object",
            "properties": {
              "children": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "groups": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "children",
              "groups"
            ]
          },
          "asOf": {
            "description": "When these facts were read.",
            "type": "string"
          }
        },
        "required": [
          "dietary",
          "service",
          "goodFor",
          "asOf"
        ]
      },
      "Orderability": {
        "type": "object",
        "properties": {
          "verdict": {
            "type": "string",
            "enum": [
              "confirmed",
              "unconfirmed",
              "unavailable"
            ]
          },
          "reason": {
            "description": "Why, when the verdict is not `confirmed` and Layout knows.",
            "type": "string",
            "enum": [
              "no_online_ordering",
              "not_a_restaurant",
              "not_offered",
              "rechecking"
            ]
          }
        },
        "required": [
          "verdict"
        ]
      },
      "PlaceDetail": {
        "type": "object",
        "properties": {
          "place": {
            "$ref": "#/components/schemas/Place"
          },
          "facts": {
            "description": "Null when Layout holds no facts for this place.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/PlaceFacts"
              },
              {
                "type": "null"
              }
            ]
          },
          "orderability": {
            "$ref": "#/components/schemas/Orderability"
          }
        },
        "required": [
          "place",
          "facts",
          "orderability"
        ]
      },
      "ItemImage": {
        "type": "object",
        "properties": {
          "url": {
            "description": "A JPEG, up to 1000px on its long side, served from Layout's CDN. Show this URL; do not copy the file.",
            "example": "https://cdn.layout.link/items/d/raisingcanes.com/the-box-combo-0e9d083ec191.jpg",
            "type": "string"
          },
          "webpUrl": {
            "description": "The same photo as WebP, smaller.",
            "type": "string"
          },
          "width": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "height": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "source": {
            "description": "`menu`: from the restaurant's own menu. `product_page`: from its own page for the item.",
            "type": "string",
            "enum": [
              "menu",
              "product_page"
            ]
          },
          "checkedAt": {
            "description": "When Layout last checked the photo against the restaurant's site (ISO 8601).",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "url",
          "webpUrl",
          "width",
          "height",
          "source",
          "checkedAt"
        ]
      },
      "ItemImageRequest": {
        "type": "object",
        "properties": {
          "item": {
            "description": "The menu item, in the person's words. Spelling and phrasing need not match the menu.",
            "example": "box combo",
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "placeId": {
            "description": "From a places or menus result. The surest way to name a store.",
            "$ref": "#/components/schemas/PlaceId"
          },
          "query": {
            "description": "A restaurant name.",
            "example": "Raising Cane's",
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "near": {
            "description": "Where, in the person's words. Not needed for a chain: its photos are the same at every branch.",
            "example": "Roseville, CA",
            "type": "string",
            "maxLength": 300
          },
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "item"
        ]
      },
      "ImageId": {
        "example": "img_Q2hJSmJsb29tQ29mZmVl",
        "type": "string",
        "pattern": "^img_[A-Za-z0-9_-]{16,2048}$"
      },
      "ImageRestaurant": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "name",
          "address"
        ]
      },
      "ItemImageResult": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "photo"
              },
              "restaurant": {
                "$ref": "#/components/schemas/ImageRestaurant"
              },
              "item": {
                "description": "The item as the restaurant names it.",
                "type": "string"
              },
              "priceMinor": {
                "description": "Their listed price in minor units when last read. Not a quote.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "image": {
                "$ref": "#/components/schemas/ItemImage"
              }
            },
            "required": [
              "status",
              "restaurant",
              "item",
              "image"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "finding"
              },
              "imageId": {
                "$ref": "#/components/schemas/ImageId"
              },
              "restaurant": {
                "$ref": "#/components/schemas/ImageRestaurant"
              },
              "retryAfterSec": {
                "description": "When to poll GET /images/items/{imageId}.",
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991
              },
              "giveUpAt": {
                "description": "When the search stops (ISO 8601), 35 seconds after the request. A poll after it answers `no_photo`.",
                "type": "string"
              }
            },
            "required": [
              "status",
              "imageId",
              "restaurant",
              "retryAfterSec",
              "giveUpAt"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "no_photo"
              },
              "restaurant": {
                "$ref": "#/components/schemas/ImageRestaurant"
              },
              "item": {
                "type": "string"
              },
              "reason": {
                "description": "`not_published`: the item is on the menu with no photo, and the menu carries photos for other items. `not_found_in_time`: Layout found no photo it could trust within 35 seconds, or the menu it read carries no photos to look in. Asking again later may find one.",
                "type": "string",
                "enum": [
                  "not_published",
                  "not_found_in_time"
                ]
              }
            },
            "required": [
              "status",
              "reason"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "not_on_menu"
              },
              "restaurant": {
                "$ref": "#/components/schemas/ImageRestaurant"
              },
              "checkedItems": {
                "description": "How many menu items were checked.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "status",
              "restaurant"
            ]
          },
          {
            "description": "`item` named no dish (only the restaurant, or a word like `food`). Ask the person which item.",
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "needs_item"
              }
            },
            "required": [
              "status"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "needs_location"
              },
              "candidates": {
                "description": "Send one back as `placeId`. Empty: send `near` or coordinates.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "placeId": {
                      "$ref": "#/components/schemas/PlaceId"
                    },
                    "name": {
                      "type": "string"
                    },
                    "address": {
                      "type": "string"
                    },
                    "distanceMi": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "placeId",
                    "name",
                    "address",
                    "distanceMi"
                  ]
                }
              }
            },
            "required": [
              "status",
              "candidates"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "not_found"
              }
            },
            "required": [
              "status"
            ]
          },
          {
            "description": "The restaurant asked Layout not to show its photos.",
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "removed"
              },
              "restaurant": {
                "$ref": "#/components/schemas/ImageRestaurant"
              }
            },
            "required": [
              "status"
            ]
          }
        ]
      },
      "MenuRequest": {
        "type": "object",
        "properties": {
          "placeId": {
            "description": "From a places or order result. The surest way to name a store.",
            "$ref": "#/components/schemas/PlaceId"
          },
          "query": {
            "description": "A restaurant name.",
            "example": "Bloom Coffee",
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "near": {
            "description": "Where, in the person's words.",
            "example": "Rocklin, CA",
            "type": "string",
            "maxLength": 300
          },
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          },
          "category": {
            "description": "One menu section, from a `categories` answer.",
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "mode": {
            "description": "`live` (default) reads the restaurant's own site. `knowledge` answers from general knowledge, labeled `live: false`, and opens nothing.",
            "type": "string",
            "enum": [
              "live",
              "knowledge"
            ]
          },
          "intent": {
            "description": "The person's own request, for a knowledge answer.",
            "type": "string",
            "maxLength": 400
          }
        }
      },
      "MenuId": {
        "example": "mnu_Q2hJSmJsb29tQ29mZmVl",
        "type": "string",
        "pattern": "^mnu_[A-Za-z0-9_-]{16,4092}$"
      },
      "MenuRestaurant": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "name",
          "address"
        ]
      },
      "MenuOptionGroup": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "moreOptions": {
            "description": "Options beyond the ones listed.",
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "defaults": {
            "description": "The options the item comes with, written as in `options`, when the restaurant preselects any. A group with defaults is already chosen: change it only when the person asks. Absent: none preselected.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name",
          "required",
          "options"
        ]
      },
      "MenuItem": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "image": {
            "description": "The restaurant's own photo of the item, when Layout already holds one. Absent: none held yet; POST /images/items finds one.",
            "$ref": "#/components/schemas/ItemImage"
          },
          "priceMinor": {
            "description": "Minor units. 429 is $4.29. Absent when the site did not give one.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "optionGroups": {
            "description": "Absent: not read. Empty: read, and the item needs no choices.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MenuOptionGroup"
            }
          },
          "soldOut": {
            "description": "The restaurant marked it sold out when the menu was read. A cart with it is refused.",
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "name"
        ]
      },
      "MenuResult": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "menu"
              },
              "restaurant": {
                "$ref": "#/components/schemas/MenuRestaurant"
              },
              "assumedNearest": {
                "description": "True when the name matched several branches and Layout read the nearest one. Tell the person which.",
                "type": "boolean"
              },
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MenuItem"
                }
              },
              "confidence": {
                "description": "`partial`: this may not be the whole menu.",
                "type": "string",
                "enum": [
                  "high",
                  "partial"
                ]
              },
              "pricesUnavailable": {
                "description": "The site gave no prices when it was read. Never fill one in.",
                "type": "boolean"
              },
              "scope": {
                "description": "`chain`: this location's own menu is not read yet or could not be read, so these are the items at least half of the restaurant's read locations list. Never priced (`pricesUnavailable` is true, since prices vary by location), and this location may not carry every item. Absent: this location's own menu.",
                "type": "string",
                "const": "chain"
              },
              "readAt": {
                "description": "When Layout read this whole menu from the site, for a menu served from that read rather than read just now. Absent: read just now.",
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"
              }
            },
            "required": [
              "status",
              "restaurant",
              "assumedNearest",
              "items",
              "confidence",
              "pricesUnavailable"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "categories"
              },
              "restaurant": {
                "$ref": "#/components/schemas/MenuRestaurant"
              },
              "assumedNearest": {
                "description": "True when the name matched several branches and Layout read the nearest one. Tell the person which.",
                "type": "boolean"
              },
              "categories": {
                "description": "Read one by sending it back as `category`.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "status",
              "restaurant",
              "assumedNearest",
              "categories"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "reading"
              },
              "menuId": {
                "$ref": "#/components/schemas/MenuId"
              },
              "restaurant": {
                "$ref": "#/components/schemas/MenuRestaurant"
              },
              "assumedNearest": {
                "description": "True when the name matched several branches and Layout read the nearest one. Tell the person which.",
                "type": "boolean"
              },
              "retryAfterSec": {
                "description": "When to poll GET /menus/{menuId}.",
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "status",
              "menuId",
              "restaurant",
              "assumedNearest",
              "retryAfterSec"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "knowledge"
              },
              "restaurant": {
                "$ref": "#/components/schemas/MenuRestaurant"
              },
              "knowledge": {
                "description": "General knowledge, not the live menu. Prices are not current.",
                "type": "string"
              },
              "live": {
                "type": "boolean",
                "const": false
              }
            },
            "required": [
              "status",
              "knowledge",
              "live"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "unreadable"
              },
              "restaurant": {
                "$ref": "#/components/schemas/MenuRestaurant"
              }
            },
            "required": [
              "status"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "not_found"
              }
            },
            "required": [
              "status"
            ]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "needs_location"
              },
              "candidates": {
                "description": "Send one back as `placeId`. Empty: send `near` or coordinates.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "placeId": {
                      "$ref": "#/components/schemas/PlaceId"
                    },
                    "name": {
                      "type": "string"
                    },
                    "address": {
                      "type": "string"
                    },
                    "distanceMi": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "placeId",
                    "name",
                    "address",
                    "distanceMi"
                  ]
                }
              }
            },
            "required": [
              "status",
              "candidates"
            ]
          }
        ]
      },
      "Geo": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "lat",
          "lng"
        ],
        "additionalProperties": false
      },
      "SandboxSimulate": {
        "description": "Sandbox only. The ending this cart reaches. `placed` when left out. See Sandbox in the reference.",
        "type": "string",
        "enum": [
          "placed",
          "failed",
          "unconfirmed",
          "challenge",
          "code",
          "card_declined",
          "price_changed",
          "closed",
          "pickup_later"
        ]
      },
      "SandboxLatency": {
        "description": "Sandbox only. `realistic` (the default) takes about as long as a real build: 30 seconds for one item and 10 for each item after it. `instant` skips every wait.",
        "type": "string",
        "enum": [
          "realistic",
          "instant"
        ]
      },
      "SandboxEngine": {
        "description": "Sandbox only. `shadow` (the default) builds from the menu Layout holds and opens no browser. `real` drives the restaurant's own site, 10 a day per developer account.",
        "type": "string",
        "enum": [
          "shadow",
          "real"
        ]
      },
      "CreateCartRequest": {
        "type": "object",
        "properties": {
          "request": {
            "description": "What the person wants, in their words.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "items": {
            "description": "One entry per item, when you have a list.",
            "minItems": 1,
            "maxItems": 10,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          },
          "placeId": {
            "description": "The store, from a places search. Sent with restaurantName, the two must name the same store, or the build is refused with `store_mismatch`.",
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,255}$"
          },
          "orderUrl": {
            "type": "string",
            "maxLength": 2000
          },
          "restaurantName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "near": {
            "description": "Where the person is, as text. Used with restaurantName.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "geo": {
            "description": "Where the person is. Used with restaurantName.",
            "$ref": "#/components/schemas/Geo"
          },
          "timeZone": {
            "type": "string",
            "maxLength": 60
          },
          "fulfillment": {
            "$ref": "#/components/schemas/FulfillmentRequest"
          },
          "tip": {
            "description": "Only with delivery.",
            "$ref": "#/components/schemas/TipRequest"
          },
          "idempotencyKey": {
            "description": "Unique per real intent. A retry with the same key and body returns the same answer. Optional when the request carries an Idempotency-Key header, whose value is then used; when both are sent, this one names the cart or the confirm.",
            "type": "string",
            "minLength": 8,
            "maxLength": 100,
            "pattern": "^[A-Za-z0-9._:-]+$"
          },
          "simulate": {
            "$ref": "#/components/schemas/SandboxSimulate"
          },
          "latency": {
            "$ref": "#/components/schemas/SandboxLatency"
          },
          "engine": {
            "$ref": "#/components/schemas/SandboxEngine"
          }
        },
        "additionalProperties": false
      },
      "AnswerCartRequest": {
        "type": "object",
        "properties": {
          "choices": {
            "description": "The person's answer to a `choices` decision, in their words.",
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "acceptPickupTime": {
            "description": "The person accepts the pickup time a `pickup_time` decision states.",
            "type": "boolean",
            "const": true
          },
          "idempotencyKey": {
            "description": "Unique per real intent. A retry with the same key and body returns the same answer. Optional when the request carries an Idempotency-Key header, whose value is then used; when both are sent, this one names the cart or the confirm.",
            "type": "string",
            "minLength": 8,
            "maxLength": 100,
            "pattern": "^[A-Za-z0-9._:-]+$"
          }
        },
        "additionalProperties": false
      },
      "ConfirmCartRequest": {
        "type": "object",
        "properties": {
          "expectedTotalMinor": {
            "description": "The cart's `totalMinor`, exactly as Layout returned it. The restaurant's total alone (`fees.merchantTotalMinor`) is refused when a fee applies.",
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "idempotencyKey": {
            "description": "Unique per real intent. A retry with the same key and body returns the same answer. Optional when the request carries an Idempotency-Key header, whose value is then used; when both are sent, this one names the cart or the confirm.",
            "type": "string",
            "minLength": 8,
            "maxLength": 100,
            "pattern": "^[A-Za-z0-9._:-]+$"
          },
          "code": {
            "type": "string",
            "pattern": "^\\d{6}$"
          }
        },
        "required": [
          "expectedTotalMinor"
        ],
        "additionalProperties": false
      },
      "DeliveryRequest": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "delivery"
          },
          "address": {
            "description": "Where to deliver, as the person would write it. Leave it out to use the person's saved default delivery address. It must be the person's own address.",
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "addressLabel": {
            "description": "One of the person's saved addresses: \"work\" or \"personal\" for the default of that kind, or the label of one from savedAddresses. Used when address is not sent.",
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "unit": {
            "description": "Apartment, suite or floor, when address does not include it.",
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "instructions": {
            "description": "Notes for the driver, for example a gate code.",
            "type": "string",
            "minLength": 1,
            "maxLength": 280
          },
          "handoff": {
            "description": "What the driver does at the door. Defaults to `leave_at_door`, with a photo.",
            "type": "string",
            "enum": [
              "leave_at_door",
              "meet_at_door"
            ]
          }
        },
        "required": [
          "type"
        ],
        "additionalProperties": false
      },
      "FulfillmentRequest": {
        "description": "`pickup`, `delivery`, or a delivery object. Leave it out for pickup. A bare `delivery` uses the person's saved default delivery address.",
        "anyOf": [
          {
            "type": "string",
            "enum": [
              "pickup",
              "delivery"
            ]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "const": "pickup"
              }
            },
            "required": [
              "type"
            ],
            "additionalProperties": false
          },
          {
            "$ref": "#/components/schemas/DeliveryRequest"
          }
        ]
      },
      "TipRequest": {
        "description": "The driver's tip, all of it to the driver. A percent of the food, or an amount in minor units. Leave it out for the lowest preset; send `{ \"percent\": 0 }` for no tip.",
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "percent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100
              }
            },
            "required": [
              "percent"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "minor": {
                "type": "integer",
                "minimum": 0,
                "maximum": 5000
              }
            },
            "required": [
              "minor"
            ],
            "additionalProperties": false
          }
        ]
      },
      "SetFulfillmentRequest": {
        "type": "object",
        "properties": {
          "fulfillment": {
            "$ref": "#/components/schemas/FulfillmentRequest"
          },
          "tip": {
            "$ref": "#/components/schemas/TipRequest"
          },
          "idempotencyKey": {
            "description": "Accepted for parity with the other cart requests. Setting the same fulfillment again is already safe to retry.",
            "type": "string",
            "minLength": 8,
            "maxLength": 100,
            "pattern": "^[A-Za-z0-9._:-]+$"
          }
        },
        "additionalProperties": false
      },
      "DeliveryUnavailableReason": {
        "description": "Why delivery is not on this cart. `not_enabled`: not offered to this person yet. `no_address`: they have no saved delivery address; send one. `out_of_range`: the store is too far from the address.",
        "type": "string",
        "enum": [
          "not_enabled",
          "no_address",
          "address_not_found",
          "no_phone",
          "out_of_range",
          "over_limit",
          "unavailable"
        ]
      },
      "CartFulfillment": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "pickup",
              "delivery"
            ]
          },
          "deliveryUnavailable": {
            "description": "Set when delivery was asked for and cannot happen. The cart stays a pickup; show the message as written.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "reason": {
                    "$ref": "#/components/schemas/DeliveryUnavailableReason"
                  },
                  "message": {
                    "type": "string"
                  },
                  "alternative": {
                    "description": "A nearer location of the same restaurant that can deliver to that address. To use it, create a new cart with its placeId and the same items and fulfillment.",
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "placeId": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "address": {
                            "type": "string"
                          },
                          "miles": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "placeId",
                          "name",
                          "address",
                          "miles"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "reason",
                  "message",
                  "alternative"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "savedAddresses": {
            "description": "The person's saved addresses, each Personal or Work, when they can choose delivery. Offer them, then send the label as addressLabel. Never coordinates or notes.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "description": "The section the person filed it under.",
                  "type": "string",
                  "enum": [
                    "personal",
                    "work"
                  ]
                },
                "label": {
                  "description": "What to call it: the name they gave it, else \"Personal\" or \"Work\".",
                  "type": "string"
                },
                "line": {
                  "type": "string"
                },
                "isDefault": {
                  "type": "boolean"
                }
              },
              "required": [
                "kind",
                "label",
                "line",
                "isDefault"
              ]
            }
          },
          "dropoff": {
            "description": "Where it is going, as one line: the street and the unit, with the person's name for it when they gave one. Never coordinates or notes.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "label": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "line": {
                    "type": "string"
                  }
                },
                "required": [
                  "label",
                  "line"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "courierFeeMinor": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "tip": {
            "description": "Show the tip and its presets beside the total. The lowest preset is chosen unless you sent a tip.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "minor": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "percent": {
                    "description": "The percent of the food you sent, or of the preset chosen for you; null for an amount you sent.",
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "presets": {
                    "description": "Suggested tips. `percent` is each amount's share of the food, rounded. On a small order they are whole-dollar steps from $2, so to choose one send its `minor`.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "percent": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "minor": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "percent",
                        "minor"
                      ]
                    }
                  }
                },
                "required": [
                  "minor",
                  "percent",
                  "presets"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "etaMinutes": {
            "description": "Delivery only: the courier's end-to-end estimate when it was quoted.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "quoteExpiresAt": {
            "description": "Delivery only: when the courier quote lapses. A confirm after it re-quotes, and a changed fee is refused with nothing charged.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "type",
          "deliveryUnavailable",
          "dropoff",
          "courierFeeMinor",
          "tip"
        ]
      },
      "CartStatus": {
        "description": "`canceling`: a cancel arrived while the cart was building. Layout releases the cart the moment the build lands, never offers it to the person, and never texts it; read the cart until it is `canceled`.",
        "type": "string",
        "enum": [
          "building",
          "ready",
          "needs_answer",
          "failed",
          "canceling",
          "canceled",
          "expired",
          "closed"
        ]
      },
      "CartItem": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "priceMinor": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "modifiers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name",
          "quantity",
          "priceMinor",
          "modifiers"
        ]
      },
      "CartFees": {
        "type": "object",
        "properties": {
          "subtotalMinor": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "taxAndFeesMinor": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "merchantTotalMinor": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "serviceFeeMinor": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "serviceFeeWaived": {
            "type": "boolean"
          },
          "creditMinor": {
            "description": "Layout credit applied when the order is placed. The card is charged totalMinor minus this.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "courierFeeMinor": {
            "description": "The delivery fee, at cost. 0 for pickup.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "tipMinor": {
            "description": "The driver's tip, all of it to the driver. 0 for pickup.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "subtotalMinor",
          "taxAndFeesMinor",
          "merchantTotalMinor",
          "serviceFeeMinor",
          "serviceFeeWaived",
          "creditMinor",
          "courierFeeMinor",
          "tipMinor"
        ]
      },
      "ChoicesDecision": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "const": "choices"
          },
          "question": {
            "type": "string"
          },
          "item": {
            "type": "string"
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "required": {
                  "type": "boolean"
                },
                "options": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "name",
                "required",
                "options"
              ]
            }
          },
          "answerWith": {
            "type": "object",
            "properties": {
              "field": {
                "type": "string",
                "const": "choices"
              }
            },
            "required": [
              "field"
            ]
          }
        },
        "required": [
          "kind",
          "question",
          "item",
          "groups",
          "answerWith"
        ]
      },
      "PickupTimeDecision": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "const": "pickup_time"
          },
          "question": {
            "type": "string"
          },
          "pickupTime": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "answerWith": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "field": {
                    "type": "string",
                    "const": "acceptPickupTime"
                  },
                  "value": {
                    "type": "boolean",
                    "const": true
                  }
                },
                "required": [
                  "field",
                  "value"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "alternatives": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "placeId": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                }
              },
              "required": [
                "placeId",
                "name",
                "address"
              ]
            }
          }
        },
        "required": [
          "kind",
          "question",
          "pickupTime",
          "answerWith",
          "alternatives"
        ]
      },
      "CartDecision": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/ChoicesDecision"
          },
          {
            "$ref": "#/components/schemas/PickupTimeDecision"
          }
        ]
      },
      "Cart": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
          },
          "status": {
            "$ref": "#/components/schemas/CartStatus"
          },
          "store": {
            "description": "The store the cart is at. Filled whenever Layout knows it, on a ready, answered, failed or closed cart alike; null only while building or when nothing names it.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "name": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "address": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "name",
                  "address"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CartItem"
            }
          },
          "currency": {
            "type": "string",
            "const": "usd"
          },
          "totalMinor": {
            "description": "The one total, delivery fee and tip included. Confirm sends exactly this as expectedTotalMinor.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "fees": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CartFees"
              },
              {
                "type": "null"
              }
            ]
          },
          "fulfillment": {
            "description": "Pickup or delivery, on a ready cart.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/CartFulfillment"
              },
              {
                "type": "null"
              }
            ]
          },
          "card": {
            "description": "The card that will be billed, on a person's token or a build grant. Show it on your confirm screen. Null when the person has no card yet.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "brand": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "last4": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "brand",
                  "last4"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "codeRequired": {
            "description": "Confirming is expected to need the 6-digit code Layout texts the person, checked each time you read the cart. `codeReason` says why. The confirm decides, and can still answer `code_required`.",
            "type": "boolean"
          },
          "codeReason": {
            "description": "Why the confirm will need the code, or null when it will not.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/CodeReason"
              },
              {
                "type": "null"
              }
            ]
          },
          "confirmationCard": {
            "description": "Layout's own wording of the cart, to show as written. Only on a connected person's token.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "decision": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CartDecision"
              },
              {
                "type": "null"
              }
            ]
          },
          "failure": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  },
                  "retryInSeconds": {
                    "description": "On `retry_blocked`: how long until a new build can start.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991
                  },
                  "orderId": {
                    "description": "On `order_in_progress`: this application's order at the same store that is confirmed and paying. Read it until it is placed or failed, then build again.",
                    "$ref": "#/components/schemas/OrderId"
                  },
                  "next": {
                    "description": "On `no_card` and `card_not_orderable`: `step` is `card_required`. For a person you provisioned there is no `url`: mint Layout's card link with POST /users/{userId}/links, send them to it, then build again. On a person's own Layout token, `url` is Layout's add-card page; send it exactly as given.",
                    "$ref": "#/components/schemas/JoinStep"
                  }
                },
                "required": [
                  "code",
                  "message"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "order": {
            "description": "The order this cart became. On a `closed` cart it was confirmed, here or on another surface, or ended: `status` is the order's state now, and `confirmedVia` names where the person confirmed it when Layout knows.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/OrderId"
                  },
                  "status": {
                    "$ref": "#/components/schemas/OrderState"
                  },
                  "confirmedVia": {
                    "$ref": "#/components/schemas/ConfirmedVia"
                  }
                },
                "required": [
                  "id",
                  "status"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "expiresAt": {
            "description": "When a ready cart stops being confirmable. Once it passes, the cart reads `expired` and a confirm is refused with `cart_closed`.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "replacedBy": {
            "description": "On a `closed` cart whose question was answered: the cart the answer started. Read that one; this one will not change again.",
            "type": "string",
            "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
          },
          "build": {
            "description": "On GET /carts/{cartId} while `status` is `building`: where the build is. Null once it is not building, or when Layout cannot tell yet. Poll the cart, not this, for the result.",
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "stage": {
                    "description": "The step the build is on: finding the store, reading the menu, building the item, heading to the cart.",
                    "type": "string",
                    "enum": [
                      "store",
                      "menu",
                      "item",
                      "cart"
                    ]
                  },
                  "etaSec": {
                    "description": "A prediction from past builds of how many seconds until the cart is ready. It can grow on a slow build.",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "stage",
                  "etaSec"
                ]
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "status",
          "store",
          "items",
          "currency",
          "totalMinor",
          "fees",
          "fulfillment",
          "card",
          "codeRequired",
          "codeReason",
          "confirmationCard",
          "decision",
          "failure",
          "order",
          "expiresAt"
        ]
      },
      "CartAccepted": {
        "type": "object",
        "properties": {
          "cart": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^crt_[0-9a-f]{10}[A-Za-z0-9_-]{11,140}$"
              },
              "status": {
                "$ref": "#/components/schemas/CartStatus"
              }
            },
            "required": [
              "id",
              "status"
            ]
          }
        },
        "required": [
          "cart"
        ]
      },
      "CartEnvelope": {
        "type": "object",
        "properties": {
          "cart": {
            "$ref": "#/components/schemas/Cart"
          }
        },
        "required": [
          "cart"
        ]
      },
      "OrderPlacing": {
        "type": "object",
        "properties": {
          "order": {
            "type": "object",
            "properties": {
              "id": {
                "$ref": "#/components/schemas/OrderId"
              },
              "status": {
                "type": "string",
                "const": "placing"
              },
              "simulated": {
                "type": "boolean",
                "const": true
              },
              "trackUrl": {
                "description": "Layout's live status page for this order, safe to show the person: it shows the store, items, total and pickup details, never the card or the person's account, and nobody can sign in with it. It follows the order while it is placed and stops answering 15 minutes after the order ends, or 3 hours after confirm at the latest. Absent when Layout could not make one. For anything later, read GET /orders/{orderId}.",
                "type": "string"
              }
            },
            "required": [
              "id",
              "status"
            ]
          }
        },
        "required": [
          "order"
        ]
      },
      "CodeSent": {
        "type": "object",
        "properties": {
          "codeSent": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "codeSent"
        ]
      },
      "Profile": {
        "type": "object",
        "properties": {
          "applyDietaryRestrictions": {
            "type": "boolean"
          },
          "preferences": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              },
              "required": [
                "category",
                "note"
              ]
            }
          }
        },
        "required": [
          "applyDietaryRestrictions",
          "preferences"
        ]
      },
      "ProfileEnvelope": {
        "type": "object",
        "properties": {
          "profile": {
            "$ref": "#/components/schemas/Profile"
          }
        },
        "required": [
          "profile"
        ]
      },
      "DailyPool": {
        "type": "object",
        "properties": {
          "name": {
            "description": "The pool. One of the developer pools, or `sandbox_builds` / `cardless_builds` for this application's own allowance.",
            "example": "builds",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "scope": {
            "description": "`developer`: every application on your developer account together. `application`: this application alone.",
            "type": "string",
            "enum": [
              "developer",
              "application"
            ]
          },
          "limit": {
            "description": "Your daily number, after any change Layout made for your account.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "used": {
            "description": "Spent today, since midnight UTC.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "remaining": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "poolLimit": {
            "description": "The pool's ceiling across every developer. When it is reached the refusal says it was Layout's limit.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "custom": {
            "description": "True when Layout set this number for your account.",
            "type": "boolean"
          },
          "note": {
            "description": "Why the pool is closed to this credential, when `limit` is 0.",
            "type": "string"
          }
        },
        "required": [
          "name",
          "description",
          "scope",
          "limit",
          "used",
          "remaining"
        ]
      },
      "RateWindow": {
        "type": "object",
        "properties": {
          "name": {
            "example": "requests",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "scope": {
            "description": "`developer`: every application on your developer account together, counted in one place. `platform`: shared by every developer on Layout, counted in one place, so your own use cannot be shown.",
            "type": "string",
            "enum": [
              "credential",
              "address",
              "person",
              "developer",
              "platform"
            ]
          },
          "period": {
            "type": "string",
            "enum": [
              "minute",
              "hour"
            ]
          },
          "limit": {
            "description": "Your number now.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "verifiedPeople": {
            "description": "On `texts` for an approved production application: the people your developer account has verified, which the hourly number grows with. Read every few minutes.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "max": {
            "description": "On `texts` for an approved production application: the most the hourly number grows to.",
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "next": {
            "description": "On `texts`, until it reaches `max`: where the number grows next.",
            "type": "object",
            "properties": {
              "verifiedPeople": {
                "description": "The verified people at which the number next grows.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "limit": {
                "description": "What it grows to.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "verifiedPeople",
              "limit"
            ]
          }
        },
        "required": [
          "name",
          "description",
          "scope",
          "period",
          "limit"
        ]
      },
      "PerPersonLimit": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "period": {
            "type": "string",
            "const": "day"
          },
          "limit": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "name",
          "description",
          "period",
          "limit"
        ]
      },
      "Usage": {
        "type": "object",
        "properties": {
          "app": {
            "type": "object",
            "properties": {
              "id": {
                "$ref": "#/components/schemas/AppId"
              }
            },
            "required": [
              "id"
            ]
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "approvalStatus": {
            "type": "string",
            "enum": [
              "pending",
              "approved",
              "denied",
              "suspended"
            ]
          },
          "resetsAt": {
            "description": "When every daily pool resets: the next midnight UTC.",
            "type": "string"
          },
          "daily": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DailyPool"
            }
          },
          "perPerson": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PerPersonLimit"
            }
          },
          "rates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RateWindow"
            }
          }
        },
        "required": [
          "app",
          "environment",
          "approvalStatus",
          "resetsAt",
          "daily",
          "perPerson",
          "rates"
        ]
      },
      "FireWebhookRequest": {
        "type": "object",
        "properties": {
          "event": {
            "description": "The event to send. `order.needs_approval` is reserved and never sent, so it cannot be fired.",
            "type": "string",
            "enum": [
              "order.building",
              "order.carted",
              "order.placing",
              "order.placed",
              "order.failed",
              "order.unconfirmed",
              "order.challenge",
              "order.updated"
            ]
          },
          "orderId": {
            "description": "One of this application's sandbox orders. The event then describes that order. Absent: a test order with ids that match nothing.",
            "$ref": "#/components/schemas/OrderId"
          }
        },
        "required": [
          "event"
        ],
        "additionalProperties": false
      },
      "FiredDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "description": "The delivery id, as the payload's `delivery_id` and the console's delivery log show it.",
            "type": "string"
          },
          "url": {
            "description": "The endpoint it went to.",
            "type": "string"
          },
          "outcome": {
            "description": "`delivered`: your endpoint answered 2xx. `retry`: it did not, and the ordinary retry schedule takes over. `dead`: retries are exhausted.",
            "type": "string",
            "enum": [
              "delivered",
              "retry",
              "dead"
            ]
          }
        },
        "required": [
          "id",
          "url",
          "outcome"
        ]
      },
      "FiredOrder": {
        "type": "object",
        "properties": {
          "id": {
            "description": "With `orderId`, that order's id. Without it, `ord_test_000000000000`, which matches nothing.",
            "type": "string"
          },
          "state": {
            "description": "The state the event carries, as a real delivery of this event would.",
            "$ref": "#/components/schemas/OrderState"
          },
          "store": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "state",
          "store"
        ]
      },
      "FireWebhookResult": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "enum": [
              "order.building",
              "order.carted",
              "order.placing",
              "order.placed",
              "order.failed",
              "order.unconfirmed",
              "order.challenge",
              "order.updated"
            ]
          },
          "order": {
            "$ref": "#/components/schemas/FiredOrder"
          },
          "deliveries": {
            "description": "One per enabled endpoint that subscribes to the event.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiredDelivery"
            }
          }
        },
        "required": [
          "event",
          "order",
          "deliveries"
        ]
      },
      "VerificationEvent": {
        "type": "object",
        "description": "Sent once when a subscription is saved or its URL changes, and again on Verify. It names no order. A 2xx turns a new subscription on or moves deliveries to a changed URL; anything else leaves it as it was. The body is never read.",
        "required": [
          "event",
          "delivery_id",
          "subscription",
          "sent_at",
          "test"
        ],
        "additionalProperties": false,
        "properties": {
          "event": {
            "type": "string",
            "const": "endpoint.verification"
          },
          "delivery_id": {
            "type": "string"
          },
          "subscription": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              }
            }
          },
          "sent_at": {
            "type": "string",
            "format": "date-time"
          },
          "test": {
            "type": "boolean",
            "const": true,
            "description": "Always true, so a handler that answers test events with a 2xx passes unchanged."
          }
        }
      }
    }
  },
  "webhooks": {
    "order": {
      "post": {
        "summary": "An order event",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges it. Anything else is retried."
          }
        }
      }
    },
    "endpointVerification": {
      "post": {
        "summary": "Endpoint verification",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerificationEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx verifies the endpoint. It is never retried, apart from one resend signed with the other environment's secret after a 4xx or 5xx."
          }
        }
      }
    }
  }
}