{
  "components": {
    "headers": {
      "IdempotentReplayed": {
        "description": "`true` when this is the stored answer to a key already seen.",
        "schema": {
          "enum": [
            "true"
          ],
          "type": "string"
        }
      },
      "Location": {
        "description": "Where the created resource, or the redirect's target, is.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before asking again.",
        "schema": {
          "minimum": 0,
          "type": "integer"
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "description": "A ULID, new for each intent and the same for its retries. The command's result is stored with it: the same key again answers the first result with `Idempotent-Replayed: true`, and the same key with a different body is 422 `idempotency-key`.",
        "example": "01JC8Z6K3W9QF2N4T7XRB5M0HD",
        "in": "header",
        "name": "Idempotency-Key",
        "required": true,
        "schema": {
          "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
          "type": "string"
        }
      },
      "IdempotencyKeyOptional": {
        "description": "Optional on a `PATCH`, which is idempotent by its body; a malformed one is still refused with 400 `idempotency-key`.",
        "in": "header",
        "name": "Idempotency-Key",
        "required": false,
        "schema": {
          "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
          "type": "string"
        }
      }
    },
    "schemas": {
      "ActivityEntry": {
        "additionalProperties": false,
        "description": "One line of the activity log.",
        "properties": {
          "at": {
            "type": "string"
          },
          "summary": {
            "description": "A short fixed sentence from the event's named fields.",
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "at",
          "type",
          "summary"
        ],
        "type": "object"
      },
      "ActivityResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/activity`: the sandbox's logged events (clock moves, faults,\nmenu and capacity changes, payment intents, orders paid, catering steps, routes, traffic,\ntoken rotations, campaigns sent and rebuilds finished), newest first\nby business time (ties by event id); `?limit=` keeps the newest that many (50 when left out,\nat most 500). Any session of the sandbox reads it.",
        "properties": {
          "entries": {
            "items": {
              "$ref": "#/components/schemas/ActivityEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "entries"
        ],
        "title": "ActivityResponse",
        "type": "object"
      },
      "BakeLineView": {
        "additionalProperties": false,
        "description": "One line of the bake list.",
        "properties": {
          "catering": {
            "description": "True for a catering event's line: `item` is the package's slug and `qty` the people it\nfeeds, not a count of items. Absent for an order's line.",
            "type": "boolean"
          },
          "item": {
            "description": "The item's slug.",
            "type": "string"
          },
          "qty": {
            "description": "Quantity to bake for this start, variants summed.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "start": {
            "description": "The slot or window start the quantity is for; an item ordered for two starts has two lines.",
            "type": "string"
          }
        },
        "required": [
          "item",
          "qty",
          "start"
        ],
        "type": "object"
      },
      "BakeListView": {
        "additionalProperties": false,
        "description": "The day's production plan, from the reserved and fulfilled places only; a held place waiting\nfor payment is not on it.",
        "properties": {
          "lines": {
            "items": {
              "$ref": "#/components/schemas/BakeLineView"
            },
            "type": "array"
          },
          "version": {
            "description": "Counts the plan's changes; 0 before the first reservation.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "version",
          "lines"
        ],
        "type": "object"
      },
      "BodyTemplate": {
        "description": "A campaign's body, chosen from a fixed list.",
        "enum": [
          "announcement",
          "fresh-bread",
          "cake-orders",
          "seasonal-menu",
          "come-back",
          "catering-invite"
        ],
        "type": "string"
      },
      "BreakerState": {
        "description": "The breaker's state, in the order it rises.",
        "oneOf": [
          {
            "const": "unconfigured",
            "description": "No run has had its token, ids and lines: the status keeps saying so.",
            "type": "string"
          },
          {
            "const": "armed",
            "description": "Running, and no window has crossed a line.",
            "type": "string"
          },
          {
            "const": "read-only",
            "description": "A window crossed a line: the flag was raised to `read-only`.",
            "type": "string"
          },
          {
            "const": "off",
            "description": "A window crossed the `off` line, or crossed a line again after `read-only`: the flag is\n`off` and the WAF kill rule is enabled.",
            "type": "string"
          }
        ]
      },
      "BreakerStatus": {
        "additionalProperties": false,
        "description": "The 15-minute cron breaker, as `Control` keeps it (kill switch L0; docs/cost.md,\n\"Guardrails\"). Every property is sent, `null` or empty when there is nothing.",
        "properties": {
          "last_run": {
            "description": "When the last run's window was handed to `Control`, an RFC 3339 UTC time.",
            "type": [
              "string",
              "null"
            ]
          },
          "last_usd": {
            "description": "The last window's usage priced in dollars with four decimals, such as `\"0.0123\"`.",
            "type": [
              "string",
              "null"
            ]
          },
          "since": {
            "description": "When the state last changed, an RFC 3339 UTC time; `null` while `unconfigured`.",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/BreakerState",
            "description": "`unconfigured` until the breaker's first configured run, then `armed`, `read-only` or\n`off`. It only rises; a person resets it."
          },
          "unread": {
            "description": "The meters the last run could not read, counted as 0, such as `[\"rows_written\"]`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "state",
          "unread",
          "last_run",
          "last_usd",
          "since"
        ],
        "type": "object"
      },
      "CampaignListResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/campaigns`: every campaign, by id.",
        "properties": {
          "campaigns": {
            "items": {
              "$ref": "#/components/schemas/CampaignResponse"
            },
            "type": "array"
          }
        },
        "required": [
          "campaigns"
        ],
        "title": "CampaignListResponse",
        "type": "object"
      },
      "CampaignRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/campaigns`, staff only: a draft, `201` with the `CampaignResponse`\n(`200` with `Idempotent-Replayed: true` for the same key again).\n`PATCH /v1/sandboxes/{id}/campaigns/{cid}` takes the same body and edits a draft: `200`, or\n`409` problem of type `campaign` naming the rule (`out-of-order`) once it is scheduled, sent\nor cancelled. A guest gets `403` `guest-scope` on both.",
        "properties": {
          "body": {
            "$ref": "#/components/schemas/BodyTemplate"
          },
          "segment": {
            "$ref": "#/components/schemas/Segment"
          },
          "subject": {
            "$ref": "#/components/schemas/SubjectTemplate"
          }
        },
        "required": [
          "subject",
          "body",
          "segment"
        ],
        "title": "CampaignRequest",
        "type": "object"
      },
      "CampaignResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/campaigns/{cid}`, and the answer to every campaign command.",
        "properties": {
          "body": {
            "$ref": "#/components/schemas/BodyTemplate"
          },
          "campaign": {
            "description": "The campaign's ULID.",
            "type": "string"
          },
          "clicked": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "delivered": {
            "description": "Messages the Inbox delivered, opened and clicked, from its events.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "opened": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "recipients": {
            "description": "The frozen recipients' count: the segment's members with marketing consent at the send.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "segment": {
            "$ref": "#/components/schemas/Segment"
          },
          "send_at": {
            "description": "While scheduled, and after the send: the business time it is due or was sent.",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/CampaignState"
          },
          "subject": {
            "$ref": "#/components/schemas/SubjectTemplate"
          }
        },
        "required": [
          "campaign",
          "state",
          "subject",
          "body",
          "segment",
          "recipients",
          "delivered",
          "opened",
          "clicked"
        ],
        "title": "CampaignResponse",
        "type": "object"
      },
      "CampaignState": {
        "description": "Where a campaign is (docs/domain.md, \"Campaign\", the diagram).",
        "enum": [
          "draft",
          "scheduled",
          "sent",
          "cancelled"
        ],
        "type": "string"
      },
      "CapacityRequest": {
        "additionalProperties": false,
        "description": "`PATCH /v1/sandboxes/{id}/schedule/{date}/capacity`, signed-in sessions only: set one\ncapacity for the day. The answer is the day's `ScheduleResponse`.",
        "properties": {
          "capacity": {
            "description": "The new capacity. Places already taken stay; a cut below them only stops new ones.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "target": {
            "description": "What to change, in the domain's grammar: `slot:HH:MM` (a slot start on the quarter hour,\nsuch as `slot:14:45`), `zone:z1` (to `z3`), `item:<slug>` (such as `item:croissant`) or\n`catering`.",
            "type": "string"
          }
        },
        "required": [
          "target",
          "capacity"
        ],
        "title": "CapacityRequest",
        "type": "object"
      },
      "CateringCancelReason": {
        "description": "Why a confirmed catering event is cancelled: a choice from a list, never free text.",
        "enum": [
          "customer_change",
          "venue_lost",
          "other"
        ],
        "type": "string"
      },
      "CateringCancelRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/catering/{cid}/cancel`, by the customer or staff, as the session\nis. Only a `confirmed` event is cancelled: `200` with the `CateringResponse`, `cancelled`,\nits `refund_deposit` true when the event day is more than 7 days away; `409` problem of type\n`catering` naming the rule (`out-of-order`) in any other state.",
        "properties": {
          "reason": {
            "$ref": "#/components/schemas/CateringCancelReason"
          }
        },
        "required": [
          "reason"
        ],
        "title": "CateringCancelRequest",
        "type": "object"
      },
      "CateringInquiryRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/catering`, the customer's inquiry; the customer is the sandbox's\npersona. `201` with the `CateringResponse` (`200` with `Idempotent-Replayed: true` for the\nsame key again). A refused inquiry is `422` problem+json naming its rule: `headcount`,\n`unknown-package`, `unknown-venue`, `closed-day`, `catering-lead` (its detail names the\n7-business-day rule and the earliest date allowed), or `brief-too-long`, `brief-email`,\n`brief-phone`, `brief-card-number` or `brief-url`, which never echo the brief.",
        "properties": {
          "brief": {
            "description": "At most 500 characters, with no email address, phone number, card number or URL.",
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "description": "The event day, `YYYY-MM-DD`: an open day (Tuesday to Sunday) at least 7 business days\nafter today.",
            "type": "string"
          },
          "headcount": {
            "description": "10 to 200 people.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "package": {
            "description": "A package slug, such as `breakfast-spread` (`pastry-platter`, `breakfast-spread`,\n`lunch-boxes`, `celebration-cake-and-coffee`).",
            "type": "string"
          },
          "venue": {
            "description": "A venue, `v1` to `v6`.",
            "type": "string"
          }
        },
        "required": [
          "date",
          "headcount",
          "package",
          "venue"
        ],
        "title": "CateringInquiryRequest",
        "type": "object"
      },
      "CateringListResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/catering`: the sandbox's catering events, the seeded eight and any\nsince, by date.",
        "properties": {
          "events": {
            "items": {
              "$ref": "#/components/schemas/CateringResponse"
            },
            "type": "array"
          }
        },
        "required": [
          "events"
        ],
        "title": "CateringListResponse",
        "type": "object"
      },
      "CateringReminder": {
        "additionalProperties": false,
        "description": "A reminder still to come, and when.",
        "properties": {
          "at": {
            "description": "A business time, such as `2026-11-19T07:00:00-07:00`.",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/ReminderKind"
          }
        },
        "required": [
          "kind",
          "at"
        ],
        "type": "object"
      },
      "CateringResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/catering/{cid}`, and the answer to every catering command: the\ninquiry, `quote`, `decline`, `accept`, `cancel`, and staff's `production` and `delivered`.\nIt mirrors the CateringEvent aggregate's state. A refused step is `409` problem of type\n`catering` naming the rule (`out-of-order`, `quote-expired`); an `accept` when the day's two\ncatering places are taken is `409` `slot-full`.",
        "properties": {
          "balance_cents": {
            "description": "`total_cents - deposit_cents`.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "brief": {
            "description": "The brief, shown back to its own sandbox only, as text.",
            "type": [
              "string",
              "null"
            ]
          },
          "catering": {
            "description": "The catering event's ULID.",
            "type": "string"
          },
          "created_at": {
            "description": "The inquiry's business time.",
            "type": "string"
          },
          "date": {
            "description": "The event day, `YYYY-MM-DD`.",
            "type": "string"
          },
          "deposit_cents": {
            "description": "25% of the total, rounded half-up.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "deposit_payment": {
            "description": "The deposit's payment ULID, once paid.",
            "type": [
              "string",
              "null"
            ]
          },
          "headcount": {
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "invoice": {
            "description": "The balance invoice's ULID, once issued.",
            "type": [
              "string",
              "null"
            ]
          },
          "invoice_due": {
            "description": "The balance invoice's due date, `YYYY-MM-DD`, 7 days after delivery.",
            "type": [
              "string",
              "null"
            ]
          },
          "package": {
            "type": "string"
          },
          "refund_deposit": {
            "description": "Set on a cancellation: whether the deposit goes back.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "reminders": {
            "description": "The reminders still to come, earliest first; empty once the event ends.",
            "items": {
              "$ref": "#/components/schemas/CateringReminder"
            },
            "type": "array"
          },
          "state": {
            "$ref": "#/components/schemas/CateringState"
          },
          "total_cents": {
            "description": "From the quote on.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "updated_at": {
            "description": "The business time of the latest change.",
            "type": "string"
          },
          "valid_until": {
            "description": "When the quote stops being accepted, a business time: 07:00 on the 14th business day\nafter the quote.",
            "type": [
              "string",
              "null"
            ]
          },
          "venue": {
            "type": "string"
          }
        },
        "required": [
          "catering",
          "state",
          "date",
          "headcount",
          "package",
          "venue",
          "reminders",
          "created_at",
          "updated_at"
        ],
        "title": "CateringResponse",
        "type": "object"
      },
      "CateringState": {
        "description": "A catering event's state (docs/domain.md, \"CateringEvent\", the diagram). `paid` is passed\nthrough in the same step as `closed`, so a response never shows it today; it is listed\nbecause the diagram has it.",
        "oneOf": [
          {
            "enum": [
              "inquiry",
              "quoted",
              "confirmed",
              "in_production",
              "delivered",
              "invoiced",
              "paid",
              "closed",
              "declined",
              "expired",
              "cancelled"
            ],
            "type": "string"
          },
          {
            "const": "accepted",
            "description": "Accepted, the day held for 15 minutes of business time while the deposit is paid.",
            "type": "string"
          }
        ]
      },
      "CateringView": {
        "additionalProperties": false,
        "description": "The day's catering capacity.",
        "properties": {
          "capacity": {
            "description": "Events the bakery takes in a day.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "taken": {
            "description": "Events held, reserved or fulfilled.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "capacity",
          "taken"
        ],
        "type": "object"
      },
      "ClockRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/clock`, signed-in sessions only: move business time forward. The\noffset only grows, at most 14 days in total.\n\nGive exactly one of `step` and `minutes`: `step` is the named step, `minutes` the older form\n(a positive count). The Worker answers 422 `clock` with rule `not-positive` for no\nadvance or for both fields, and rule `offset-cap` when the 14 days would be passed.",
        "properties": {
          "minutes": {
            "description": "The compatible older form: minutes to advance, 1 or more.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "step": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ClockStep"
              },
              {
                "type": "null"
              }
            ],
            "description": "`15m`, `1h`, `1d` or `next-opening`."
          }
        },
        "title": "ClockRequest",
        "type": "object"
      },
      "ClockResponse": {
        "additionalProperties": false,
        "description": "The business clock after an advance.",
        "properties": {
          "business_now": {
            "description": "Business time now, such as `2026-11-07T09:42:10-07:00`, shown at America/Denver's offset\nat that instant (`-06:00` in summer).",
            "type": "string"
          },
          "clock_offset_s": {
            "description": "Seconds of business time ahead of wall time, 0 to 14 days.",
            "format": "int64",
            "type": "integer"
          },
          "clock_v": {
            "description": "Counts the advances; a child that has not heard of the latest one is retried.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "step": {
            "description": "The step applied, in its wire form: `15m`, `1h`, `1d`, `next-opening`, or `<n>m` for the\nolder `minutes` form.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "clock_offset_s",
          "clock_v",
          "business_now"
        ],
        "title": "ClockResponse",
        "type": "object"
      },
      "ClockStep": {
        "description": "How far one clock advance moves business time.",
        "oneOf": [
          {
            "const": "15m",
            "description": "15 minutes.",
            "type": "string"
          },
          {
            "const": "1h",
            "description": "One hour.",
            "type": "string"
          },
          {
            "const": "1d",
            "description": "One day: 86,400 seconds of business time, so across a clock change the local time moves\nby an hour.",
            "type": "string"
          },
          {
            "const": "next-opening",
            "description": "To the next 07:00 on an open day (Tuesday to Sunday) after business time now.",
            "type": "string"
          }
        ]
      },
      "ComparisonView": {
        "additionalProperties": false,
        "description": "The two plans' totals side by side.",
        "properties": {
          "browser_minutes": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "gap_percent": {
            "description": "`(server − browser) / browser × 100`, to one decimal: positive when the heuristic drives\nlonger. `null` when the browser's plan drives 0 minutes and the server's does not.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "server_minutes": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "server_minutes",
          "browser_minutes"
        ],
        "type": "object"
      },
      "CompleteStopRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/dispatch/{date}/complete`, staff only: a stop of the published plan\nis delivered. Again for a delivered stop changes nothing. Refused 409 `not-ready` while the\nstop's order is still confirmed or in production: the kitchen marks it ready first.",
        "properties": {
          "stop": {
            "description": "The stop's number in the published plan, from 1.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "stop"
        ],
        "title": "CompleteStopRequest",
        "type": "object"
      },
      "ConsentRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/customers/{cid}/consent`, by that customer's persona or by staff:\n`200` with the `CustomerResponse`; the same value again changes nothing and answers `200`.",
        "properties": {
          "marketing": {
            "type": "boolean"
          }
        },
        "required": [
          "marketing"
        ],
        "title": "ConsentRequest",
        "type": "object"
      },
      "CountersState": {
        "description": "How fresh `counters` are.",
        "oneOf": [
          {
            "const": "live",
            "description": "Refreshed within the last 20 minutes.",
            "type": "string"
          },
          {
            "const": "stale",
            "description": "An older snapshot: the last refresh failed, or none has run for 20 minutes. The\nfailure's reason is in the Worker's log only.",
            "type": "string"
          },
          {
            "const": "unavailable",
            "description": "No snapshot yet.",
            "type": "string"
          }
        ]
      },
      "CreateSandboxRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes`. A guest needs `turnstile_token`; an account that already has a live\nsandbox gets it back unless `replace` is true.",
        "properties": {
          "replace": {
            "default": false,
            "type": "boolean"
          },
          "turnstile_token": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "CreateSandboxRequest",
        "type": "object"
      },
      "CustomerListResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/customers`: the 60 personas, by id.",
        "properties": {
          "customers": {
            "items": {
              "$ref": "#/components/schemas/CustomerResponse"
            },
            "type": "array"
          }
        },
        "required": [
          "customers"
        ],
        "title": "CustomerListResponse",
        "type": "object"
      },
      "CustomerResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/customers/{cid}`, and the answer to a consent change: one persona as\nCrm's projection holds it. Every field is synthetic; there is no contact of any kind.",
        "properties": {
          "catering": {
            "description": "Catering inquiries.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "customer": {
            "description": "The customer's ULID.",
            "type": "string"
          },
          "display_name": {
            "description": "Two generic words, such as `Drizzle Trowel`.",
            "type": "string"
          },
          "home_zone": {
            "description": "`z1` to `z3`.",
            "type": "string"
          },
          "last_order_at": {
            "description": "The latest such order's slot, a business time.",
            "type": [
              "string",
              "null"
            ]
          },
          "loyalty_points": {
            "description": "Loyalty points: one per whole dollar paid, less refunds; never below zero.",
            "format": "int64",
            "type": "integer"
          },
          "marketing": {
            "description": "Consent to marketing: a campaign goes only to customers for whom it is true at the send.",
            "type": "boolean"
          },
          "orders": {
            "description": "Orders paid, or closed in the seed's history, and not cancelled.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "place": {
            "description": "`p1` to `p64`, a map label: the only address there is.",
            "type": "string"
          },
          "preferences": {
            "description": "One to three item slugs.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "customer",
          "display_name",
          "preferences",
          "home_zone",
          "place",
          "marketing",
          "loyalty_points",
          "orders",
          "catering"
        ],
        "title": "CustomerResponse",
        "type": "object"
      },
      "DeadLetter": {
        "additionalProperties": false,
        "description": "One message the Queue gave up on after 3 retries, from `GET /v1/sandboxes/{id}/dead-letters`\n(an array of these), and the answer to a redrive.",
        "properties": {
          "at": {
            "description": "When it was dead-lettered, a wall time.",
            "type": "string"
          },
          "error": {
            "description": "The last delivery error, as a reason code such as `Kitchen answered 503`.",
            "type": "string"
          },
          "id": {
            "description": "The event's ULID: the key a redrive sends it again with.",
            "type": "string"
          },
          "seq": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "stream": {
            "description": "The producing object's name.",
            "type": "string"
          },
          "type": {
            "description": "The event type, such as `OrderPlaced`.",
            "type": "string"
          }
        },
        "required": [
          "id",
          "type",
          "stream",
          "seq",
          "error",
          "at"
        ],
        "title": "DeadLetter",
        "type": "object"
      },
      "DeclineReason": {
        "description": "Why staff decline an inquiry: a choice from a list, never free text.",
        "enum": [
          "too_soon",
          "over_capacity",
          "other"
        ],
        "type": "string"
      },
      "DeclineRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/catering/{cid}/decline`, staff only, while the inquiry is an\n`inquiry`. `200` with the `CateringResponse`, `declined`; `409` problem of type `catering`\nnaming the rule (`out-of-order`) once it is quoted.",
        "properties": {
          "reason": {
            "$ref": "#/components/schemas/DeclineReason"
          }
        },
        "required": [
          "reason"
        ],
        "title": "DeclineRequest",
        "type": "object"
      },
      "DemoSigninRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/demo/signin`.",
        "properties": {
          "password": {
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "username",
          "password"
        ],
        "title": "DemoSigninRequest",
        "type": "object"
      },
      "DemoSignupRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/auth/demo`. The password never reaches an object, a log or this type's `Debug`.",
        "properties": {
          "password": {
            "description": "12 to 128 characters, no composition rules.",
            "type": "string"
          },
          "turnstile_token": {
            "type": "string"
          }
        },
        "required": [
          "password",
          "turnstile_token"
        ],
        "title": "DemoSignupRequest",
        "type": "object"
      },
      "DemoSignupResponse": {
        "additionalProperties": false,
        "description": "`201` from `POST /v1/auth/demo`: the generated username, shown once.",
        "properties": {
          "username": {
            "description": "`baker-` and four characters, such as `baker-7f3k`.",
            "type": "string"
          }
        },
        "required": [
          "username"
        ],
        "title": "DemoSignupResponse",
        "type": "object"
      },
      "DispatchResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/dispatch/{date}`, which any session of the sandbox reads, and the\nanswer to every dispatch command, which are staff only: one bakery day's stops and plans. It mirrors the Dispatch aggregate's state.",
        "properties": {
          "capacity": {
            "description": "Units a van carries: the last proposal's, 250 before any.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "comparison": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ComparisonView"
              },
              {
                "type": "null"
              }
            ],
            "description": "Both plans' totals, when there are both; `null` while the browser's solver has not run\nor cannot (the page then shows the server's plan alone and says why)."
          },
          "date": {
            "description": "The bakery day, `YYYY-MM-DD`.",
            "type": "string"
          },
          "plan_v": {
            "description": "The published plan's version, 0 before the first publish.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "proposed": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PlanView"
              },
              {
                "type": "null"
              }
            ],
            "description": "The server's plan from the last `propose`."
          },
          "published": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PlanView"
              },
              {
                "type": "null"
              }
            ],
            "description": "The record: what drivers, the kitchen board and the order status read."
          },
          "stops": {
            "description": "Every stop the day has seen, removed ones included, by order ULID.",
            "items": {
              "$ref": "#/components/schemas/StopView"
            },
            "type": "array"
          },
          "submitted": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PlanView"
              },
              {
                "type": "null"
              }
            ],
            "description": "The browser's plan from the last `plan`, validated."
          },
          "vans": {
            "description": "The day's vans, 1 to 4: the last proposal's, 4 before any.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "date",
          "vans",
          "capacity",
          "stops",
          "plan_v"
        ],
        "title": "DispatchResponse",
        "type": "object"
      },
      "FaultName": {
        "description": "The faults a visitor may set.",
        "enum": [
          "inbox",
          "kitchen"
        ],
        "type": "string"
      },
      "FaultRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/faults`, signed-in sessions only.",
        "properties": {
          "fault": {
            "$ref": "#/components/schemas/FaultName"
          },
          "on": {
            "type": "boolean"
          }
        },
        "required": [
          "fault",
          "on"
        ],
        "title": "FaultRequest",
        "type": "object"
      },
      "Faults": {
        "additionalProperties": false,
        "description": "The sandbox's fault switches: the Queue Lab's broken subscriber, live. `kitchen` makes the\nKitchen refuse every delivery with 503, so a message retries three times and lands in the\ndead-letter queue (PR 4); `inbox` does the same to the Inbox when it arrives (PR 8).",
        "properties": {
          "inbox": {
            "type": "boolean"
          },
          "kitchen": {
            "type": "boolean"
          }
        },
        "required": [
          "inbox",
          "kitchen"
        ],
        "type": "object"
      },
      "FaultsResponse": {
        "additionalProperties": false,
        "description": "The answer to a fault change: every switch as it now stands.",
        "properties": {
          "faults": {
            "$ref": "#/components/schemas/Faults"
          }
        },
        "required": [
          "faults"
        ],
        "title": "FaultsResponse",
        "type": "object"
      },
      "Flag": {
        "description": "The demo's mode, set in `Control` (kill switch L1).",
        "oneOf": [
          {
            "const": "live",
            "description": "Everything works.",
            "type": "string"
          },
          {
            "const": "read-only",
            "description": "Reads work; commands get 503.",
            "type": "string"
          },
          {
            "const": "off",
            "description": "Only the storefront's static pages work.",
            "type": "string"
          }
        ]
      },
      "HealthResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/health`: the Worker answers, and which build it is. Touches no object.",
        "properties": {
          "commit": {
            "description": "The commit the bundle was built from; `dev` on a laptop.",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/HealthStatus"
          },
          "version": {
            "description": "The API's version.",
            "type": "string"
          }
        },
        "required": [
          "status",
          "commit",
          "version"
        ],
        "title": "HealthResponse",
        "type": "object"
      },
      "HealthStatus": {
        "enum": [
          "ok"
        ],
        "type": "string"
      },
      "InboxResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/inbox`: the newest messages first, and how many there are in all.\n`?kind=` keeps one kind, `?to=` one customer's, `?limit=` the newest that many (50 when left\nout, at most 500). Any session of the sandbox, a guest's included, sees every customer's\nmessages: the persona is not filtered to its own, and `?to=` is how a reader narrows to one.",
        "properties": {
          "messages": {
            "items": {
              "$ref": "#/components/schemas/MessageResponse"
            },
            "type": "array"
          },
          "total": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "messages",
          "total"
        ],
        "title": "InboxResponse",
        "type": "object"
      },
      "ItemCapView": {
        "additionalProperties": false,
        "description": "One item's daily cap and use.",
        "properties": {
          "daily_cap": {
            "description": "The most the kitchen bakes of it in a day; `null` when the item has no cap.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "item": {
            "description": "The item's slug.",
            "type": "string"
          },
          "used": {
            "description": "Quantity on the day's places that count (held, reserved or fulfilled), variants summed.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "item",
          "used"
        ],
        "type": "object"
      },
      "LastWipe": {
        "additionalProperties": false,
        "description": "One nightly wipe, as its `wipe` point recorded it.",
        "properties": {
          "at": {
            "description": "When the point was written, at the wipe's end: an RFC 3339 UTC time such as\n`2026-11-06T10:00:04Z`.",
            "type": "string"
          },
          "ms": {
            "description": "Milliseconds from the 10:00 UTC cron to the wipe's last run.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "objects": {
            "description": "Objects those sandboxes emptied, each Sandbox and its children.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "sandboxes": {
            "description": "Sandboxes the wipe ended.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "at",
          "sandboxes",
          "objects",
          "ms"
        ],
        "type": "object"
      },
      "LeadPipelineResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/leads`: every stage, in order, with its catering events.",
        "properties": {
          "stages": {
            "items": {
              "$ref": "#/components/schemas/LeadStageView"
            },
            "type": "array"
          }
        },
        "required": [
          "stages"
        ],
        "title": "LeadPipelineResponse",
        "type": "object"
      },
      "LeadStage": {
        "description": "A catering lead's stage in Crm's pipeline.",
        "oneOf": [
          {
            "enum": [
              "inquiry",
              "quoted",
              "accepted",
              "closed"
            ],
            "type": "string"
          },
          {
            "const": "won",
            "description": "The deposit is paid.",
            "type": "string"
          },
          {
            "const": "lost",
            "description": "Declined, expired or cancelled.",
            "type": "string"
          }
        ]
      },
      "LeadStageView": {
        "additionalProperties": false,
        "properties": {
          "count": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "events": {
            "description": "The catering events' ULIDs.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "stage": {
            "$ref": "#/components/schemas/LeadStage"
          }
        },
        "required": [
          "stage",
          "count",
          "events"
        ],
        "type": "object"
      },
      "LedgerEntry": {
        "additionalProperties": false,
        "description": "One line of the ledger: a payment's success or a refund issued.",
        "properties": {
          "amount_cents": {
            "description": "Signed: positive for a payment, negative for a refund.",
            "format": "int64",
            "type": "integer"
          },
          "at": {
            "description": "The business time of the event that made it.",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/LedgerKind"
          },
          "purpose": {
            "$ref": "#/components/schemas/PaymentPurpose"
          },
          "ref": {
            "description": "The order or catering job's ULID.",
            "type": "string"
          },
          "stripe_id": {
            "description": "Stripe's id: the intent's `pi_...` for a payment, the refund's `re_...` for a refund;\n`seed:<payment>` for a seeded order's payment, which the seed made and Stripe never saw.",
            "type": "string"
          }
        },
        "required": [
          "at",
          "kind",
          "purpose",
          "ref",
          "amount_cents",
          "stripe_id"
        ],
        "type": "object"
      },
      "LedgerKind": {
        "enum": [
          "payment",
          "refund"
        ],
        "type": "string"
      },
      "LedgerResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/billing/ledger`: every entry in order, and the totals.",
        "properties": {
          "entries": {
            "items": {
              "$ref": "#/components/schemas/LedgerEntry"
            },
            "type": "array"
          },
          "net_cents": {
            "description": "`paid_cents - refunded_cents`.",
            "format": "int64",
            "type": "integer"
          },
          "paid_cents": {
            "format": "int64",
            "type": "integer"
          },
          "refunded_cents": {
            "description": "A positive amount.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "entries",
          "net_cents",
          "paid_cents",
          "refunded_cents"
        ],
        "title": "LedgerResponse",
        "type": "object"
      },
      "MatrixPlace": {
        "additionalProperties": false,
        "description": "One place of the travel-time matrix.",
        "properties": {
          "index": {
            "description": "0 to the places' count less one, in order.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          },
          "label": {
            "description": "The map label, `p1` to `p64`; no name, coordinate or street.",
            "type": "string"
          }
        },
        "required": [
          "index",
          "label"
        ],
        "type": "object"
      },
      "MatrixResponse": {
        "description": "The travel-time matrix the dispatch screen loads to run VROOM. It is not an API response: it\nis a static asset of the web Worker, the same JSON as the committed fixture\n`crates/seed/data/<city>/matrix.json` (ADR 0012, decision 7), and this type only fixes its\nshape.",
        "properties": {
          "built": {
            "description": "When the build ran, or `seed:<n>` for the synthetic city.",
            "type": "string"
          },
          "city": {
            "description": "The city the build is for, or `synthetic`.",
            "type": "string"
          },
          "depot": {
            "default": 0,
            "description": "The bakery's place, where every route starts and ends; 0 when left out.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          },
          "minutes": {
            "description": "`minutes[i][j]`: whole minutes driving from place `i` to place `j`, 0 on the diagonal.\nNot necessarily symmetric.",
            "items": {
              "items": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "type": "array"
            },
            "type": "array"
          },
          "places": {
            "items": {
              "$ref": "#/components/schemas/MatrixPlace"
            },
            "type": "array"
          },
          "source": {
            "description": "Where the travel times come from, with the attribution the data's licence asks for.",
            "type": "string"
          }
        },
        "required": [
          "city",
          "built",
          "source",
          "places",
          "minutes"
        ],
        "title": "MatrixResponse",
        "type": "object"
      },
      "MenuBulkLead": {
        "additionalProperties": false,
        "description": "More than `over_qty` of one variant needs `lead_minutes`.",
        "properties": {
          "lead_minutes": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "over_qty": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "over_qty",
          "lead_minutes"
        ],
        "type": "object"
      },
      "MenuCategory": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/MenuItem"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          }
        },
        "required": [
          "slug",
          "name",
          "items"
        ],
        "type": "object"
      },
      "MenuDraft": {
        "additionalProperties": false,
        "description": "One item with edits waiting for a publish, as its draft copy stands: the variants carry\ntheir draft prices.",
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/MenuItemState",
            "description": "The draft copy's status: `draft` for an item never published, else the published one,\nsince a pause or a resume is never a draft."
          },
          "variants": {
            "items": {
              "$ref": "#/components/schemas/MenuVariant"
            },
            "type": "array"
          }
        },
        "required": [
          "slug",
          "name",
          "status",
          "variants"
        ],
        "type": "object"
      },
      "MenuDraftsResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/menu/drafts`, signed-in sessions only: every item with a draft\nwaiting for `POST .../menu/publish`, in slug order, and the published version. The console's\nmenu editor reads it with `GET .../menu` on load and again after a publish, and shows each\nitem's waiting price under its published one, so a draft made before a reload is still shown.\nThe published prices are in the menu it already holds, so they are not repeated here.",
        "properties": {
          "pending": {
            "items": {
              "$ref": "#/components/schemas/MenuDraft"
            },
            "type": "array"
          },
          "version": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "version",
          "pending"
        ],
        "title": "MenuDraftsResponse",
        "type": "object"
      },
      "MenuEditResponse": {
        "additionalProperties": false,
        "description": "The answer to a staff edit or a publish: the published version and the items with drafts\nstill waiting for a publish.",
        "properties": {
          "pending": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "version": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "version",
          "pending"
        ],
        "title": "MenuEditResponse",
        "type": "object"
      },
      "MenuItem": {
        "additionalProperties": false,
        "properties": {
          "allergens": {
            "description": "From the nine major US allergens, such as `wheat` and `tree-nuts`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "bulk_lead": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MenuBulkLead"
              },
              {
                "type": "null"
              }
            ]
          },
          "daily_cap": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "days_baked": {
            "description": "`mon` to `sun`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "pickup_only": {
            "type": "boolean"
          },
          "season": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MenuSeason"
              },
              {
                "type": "null"
              }
            ]
          },
          "slug": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/MenuItemState"
          },
          "variants": {
            "items": {
              "$ref": "#/components/schemas/MenuVariant"
            },
            "type": "array"
          }
        },
        "required": [
          "slug",
          "name",
          "allergens",
          "daily_cap",
          "days_baked",
          "pickup_only",
          "status",
          "variants"
        ],
        "type": "object"
      },
      "MenuItemPatch": {
        "additionalProperties": false,
        "description": "`PATCH /v1/sandboxes/{id}/menu/items/{slug}`, signed-in sessions only. A price is a draft,\nset on every variant of the item, until `POST .../menu/publish`; a pause or a resume\npublishes that one item at once.",
        "properties": {
          "price_cents": {
            "default": null,
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MenuItemStatus"
              },
              {
                "type": "null"
              }
            ],
            "default": null
          }
        },
        "title": "MenuItemPatch",
        "type": "object"
      },
      "MenuItemState": {
        "description": "An item's stored lifecycle; the menu lists `available` and `paused` items.",
        "enum": [
          "draft",
          "available",
          "paused",
          "retired"
        ],
        "type": "string"
      },
      "MenuItemStatus": {
        "description": "What a staff edit may set on a menu item's status.",
        "enum": [
          "paused",
          "available"
        ],
        "type": "string"
      },
      "MenuResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/menu`: the published menu, with `ETag: \"v<version>\"`.",
        "properties": {
          "categories": {
            "items": {
              "$ref": "#/components/schemas/MenuCategory"
            },
            "type": "array"
          },
          "version": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "version",
          "categories"
        ],
        "title": "MenuResponse",
        "type": "object"
      },
      "MenuSeason": {
        "additionalProperties": false,
        "description": "A seasonal window, `MM-DD` to `MM-DD` inclusive, wrapping over the new year when `from` is\nafter `to`.",
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "MenuVariant": {
        "additionalProperties": false,
        "properties": {
          "label": {
            "type": "string"
          },
          "lead_minutes": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "price_cents": {
            "format": "int64",
            "type": "integer"
          },
          "slug": {
            "description": "`<item slug>/<suffix>`, such as `croissant/box-6`.",
            "type": "string"
          }
        },
        "required": [
          "slug",
          "label",
          "price_cents",
          "lead_minutes"
        ],
        "type": "object"
      },
      "MessageKind": {
        "description": "What a message is.",
        "enum": [
          "receipt",
          "ready",
          "on_its_way",
          "refund",
          "declined",
          "acknowledgement",
          "quote",
          "notice",
          "reminder",
          "invoice",
          "campaign"
        ],
        "type": "string"
      },
      "MessageResponse": {
        "additionalProperties": false,
        "description": "One message in the sandbox's inbox, and `GET /v1/sandboxes/{id}/inbox/{mid}`.",
        "properties": {
          "body": {
            "type": "string"
          },
          "clicked_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "delivered_at": {
            "description": "Business times.",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/MessageKind"
          },
          "message": {
            "description": "The message's ULID.",
            "type": "string"
          },
          "opened_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "ref": {
            "description": "The ULID of the order, catering event or campaign it is about.",
            "type": "string"
          },
          "subject": {
            "description": "From a fixed template, filled with the event's own figures; never free text.",
            "type": "string"
          },
          "to": {
            "description": "The customer's ULID: the only recipient there is.",
            "type": "string"
          }
        },
        "required": [
          "message",
          "to",
          "kind",
          "ref",
          "subject",
          "body",
          "delivered_at"
        ],
        "title": "MessageResponse",
        "type": "object"
      },
      "OrderKind": {
        "description": "Pickup at the counter, or delivery to a zone.",
        "enum": [
          "pickup",
          "delivery"
        ],
        "type": "string"
      },
      "OrderLineRequest": {
        "additionalProperties": false,
        "description": "One line of an order as the customer asks for it.",
        "properties": {
          "qty": {
            "description": "1 to 24.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "variant": {
            "description": "A variant slug from the menu, such as `croissant/box-6`.",
            "type": "string"
          }
        },
        "required": [
          "variant",
          "qty"
        ],
        "type": "object"
      },
      "OrderLineResponse": {
        "additionalProperties": false,
        "description": "A placed line, priced from the menu version the order names; never repriced.",
        "properties": {
          "item": {
            "type": "string"
          },
          "qty": {
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "unit_cents": {
            "format": "int64",
            "type": "integer"
          },
          "variant": {
            "type": "string"
          }
        },
        "required": [
          "item",
          "variant",
          "qty",
          "unit_cents"
        ],
        "title": "OrderLineResponse",
        "type": "object"
      },
      "OrderRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/orders`. The customer is the sandbox's persona; the prices come\nfrom the menu version the Catalog publishes when the order is placed.",
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/OrderKind"
          },
          "lines": {
            "description": "1 to 20 lines.",
            "items": {
              "$ref": "#/components/schemas/OrderLineRequest"
            },
            "type": "array"
          },
          "note": {
            "default": null,
            "description": "At most 140 characters, with no email address, phone number, card number or URL.",
            "type": [
              "string",
              "null"
            ]
          },
          "slot": {
            "description": "The pickup slot's or delivery window's start, a business time such as\n`2026-11-07T09:45:00-07:00`.",
            "type": "string"
          },
          "zone": {
            "default": null,
            "description": "`z1`, `z2` or `z3` for a delivery; absent for a pickup.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "kind",
          "slot",
          "lines"
        ],
        "title": "OrderRequest",
        "type": "object"
      },
      "OrderResponse": {
        "additionalProperties": false,
        "description": "`201` from placing an order (`200` with `Idempotent-Replayed: true` for the same key again),\n`GET /v1/sandboxes/{id}/orders/{oid}`, and the answer to a cancel.",
        "properties": {
          "events_seq": {
            "description": "The `seq` of the order's latest event.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "held_until": {
            "description": "When an unpaid order expires, 15 minutes of business time after `placed_at`.",
            "type": "string"
          },
          "id": {
            "description": "The order's ULID.",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/OrderKind"
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/OrderLineResponse"
            },
            "type": "array"
          },
          "menu_version": {
            "description": "The published menu version the prices came from.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "placed_at": {
            "description": "When the order was placed, a business time.",
            "type": "string"
          },
          "slot": {
            "description": "A business time.",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "subtotal_cents": {
            "format": "int64",
            "type": "integer"
          },
          "tax_cents": {
            "format": "int64",
            "type": "integer"
          },
          "total_cents": {
            "format": "int64",
            "type": "integer"
          },
          "zone": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "status",
          "kind",
          "slot",
          "lines",
          "subtotal_cents",
          "tax_cents",
          "total_cents",
          "placed_at",
          "held_until",
          "menu_version",
          "events_seq"
        ],
        "title": "OrderResponse",
        "type": "object"
      },
      "OrderStatus": {
        "description": "An order's state (docs/domain.md, \"Order\", the diagram).",
        "enum": [
          "placed",
          "confirmed",
          "expired",
          "cancelled",
          "refund_pending",
          "in_production",
          "ready",
          "picked_up",
          "out_for_delivery",
          "delivered",
          "closed"
        ],
        "type": "string"
      },
      "PaymentPurpose": {
        "description": "What a payment pays for.",
        "enum": [
          "order",
          "deposit",
          "balance"
        ],
        "type": "string"
      },
      "PaymentResponse": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/orders/{oid}/payment`: what the browser needs to mount Stripe's\nPayment Element. `client_secret` is a one-time value for the browser: it is not stored, not\nlogged, and left out of this type's `Debug`.",
        "properties": {
          "amount_cents": {
            "format": "int64",
            "type": "integer"
          },
          "client_secret": {
            "description": "Stripe's `pi_..._secret_...`, for `<Elements options={{ clientSecret }}>`.",
            "type": "string"
          },
          "payment": {
            "description": "Billing's id for the payment, a ULID.",
            "type": "string"
          },
          "publishable_key": {
            "default": null,
            "description": "The sandbox's `pk_test_` key, when the API has one to give; the storefront's own build\nvalue otherwise.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/PaymentStatus"
          }
        },
        "required": [
          "payment",
          "client_secret",
          "amount_cents",
          "status"
        ],
        "title": "PaymentResponse",
        "type": "object"
      },
      "PaymentStatus": {
        "description": "Where a payment stands (docs/domain.md, the Billing rows).",
        "oneOf": [
          {
            "enum": [
              "succeeded",
              "canceled"
            ],
            "type": "string"
          },
          {
            "const": "created",
            "description": "Asked for; waiting for the browser.",
            "type": "string"
          },
          {
            "const": "failed",
            "description": "The last attempt was declined; the same intent can still be paid.",
            "type": "string"
          }
        ]
      },
      "PersonaAddress": {
        "additionalProperties": false,
        "description": "A made-up address, labelled synthetic in its first line, passed to Stripe's\n`confirmPayment` as the billing address.",
        "properties": {
          "city": {
            "type": "string"
          },
          "country": {
            "description": "An ISO 3166-1 alpha-2 code.",
            "type": "string"
          },
          "line1": {
            "description": "`<place label>, unit <n> (synthetic)`, such as `p17, unit 3 (synthetic)`.",
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "state": {
            "description": "A two-letter state code.",
            "type": "string"
          }
        },
        "required": [
          "line1",
          "city",
          "state",
          "postal_code",
          "country"
        ],
        "type": "object"
      },
      "PlanChoice": {
        "description": "Which stored plan to publish.",
        "oneOf": [
          {
            "const": "proposed",
            "description": "The server's.",
            "type": "string"
          },
          {
            "const": "submitted",
            "description": "The browser's.",
            "type": "string"
          }
        ]
      },
      "PlanRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/dispatch/{date}/plan`, staff only: the plan VROOM made in the\nbrowser. It carries no minutes: the server computes them from the matrix. Refused with 422\n`stop-missing`, `stop-twice`, `stop-unknown`, `over-capacity`, `route-ends`, `vans`,\n`window` or `no-stops`. `window`: the vans leave the bakery at 09:00, a van early at a door\nwaits for the stop's window to open and spends 3 minutes there, and each stop must be\nreached by its window's close (`StopView.window` plus 120 minutes).",
        "properties": {
          "vans": {
            "items": {
              "$ref": "#/components/schemas/PlanRouteRequest"
            },
            "type": "array"
          }
        },
        "required": [
          "vans"
        ],
        "title": "PlanRequest",
        "type": "object"
      },
      "PlanRouteRequest": {
        "additionalProperties": false,
        "description": "One van of the browser's plan.",
        "properties": {
          "end": {
            "description": "The place the van comes back to; the same rule.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "start": {
            "description": "The place the van leaves from, as the solver reports it; it must be the bakery, and is\ntaken to be when left out.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "stops": {
            "description": "Order ULIDs, in driving order. An empty list is a van left at the bakery.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "van": {
            "description": "1 to the day's vans, each once.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "van",
          "stops"
        ],
        "type": "object"
      },
      "PlanSource": {
        "description": "Who made a plan: the server's savings heuristic or the browser's VROOM solver.",
        "enum": [
          "server",
          "browser"
        ],
        "type": "string"
      },
      "PlanView": {
        "additionalProperties": false,
        "description": "A plan as the dispatch screen shows it (ADR 0012, decision 5). Its minutes are the server's\nown arithmetic over the matrix, whoever made the plan.",
        "properties": {
          "last_back": {
            "description": "When the last van is back, a business time: the vans leave at 09:00, drive the matrix's\nminutes, spend 3 minutes at each door and wait at a door they reach before its window\nopens.",
            "type": "string"
          },
          "minutes": {
            "description": "Every van's drive summed.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "plan_v": {
            "description": "A published plan's version. A proposal or submission carries the version it would be\npublished as when it was made; one at or below the response's `plan_v` is stale.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "source": {
            "$ref": "#/components/schemas/PlanSource"
          },
          "unassigned": {
            "description": "Order ULIDs no van could take. A plan with any cannot be published.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "vans": {
            "description": "The vans used, by van; a plan may use fewer than the day has.",
            "items": {
              "$ref": "#/components/schemas/VanPlanView"
            },
            "type": "array"
          }
        },
        "required": [
          "source",
          "plan_v",
          "vans",
          "minutes",
          "last_back",
          "unassigned"
        ],
        "type": "object"
      },
      "Problem": {
        "description": "An error body, `application/problem+json` (RFC 9457).",
        "properties": {
          "detail": {
            "description": "What went wrong this time, for a person to read.",
            "type": [
              "string",
              "null"
            ]
          },
          "instance": {
            "description": "The request path this occurrence concerns.",
            "type": [
              "string",
              "null"
            ]
          },
          "next_free": {
            "description": "An extension member (RFC 9457, section 3.2), set only on the `slot-full` and `hold-lost`\nproblems: the start of the next pickup slot with a place free that day, a business time\nsuch as `2026-11-07T10:15:00-07:00`. Absent when nothing later that day is free, and on\nevery other problem.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "description": "The HTTP status code.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "title": {
            "description": "A short summary that does not change between occurrences.",
            "type": "string"
          },
          "type": {
            "description": "A URI reference naming the problem type; `about:blank` when the status says it all.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "status"
        ],
        "title": "Problem",
        "type": "object"
      },
      "ProposeRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/dispatch/{date}/propose`, staff only: the server's plan for the\nconfirmed stops. The vans and capacity become the day's.",
        "properties": {
          "capacity": {
            "description": "Units a van carries, at least 1.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "vans": {
            "description": "1 to 4.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "vans",
          "capacity"
        ],
        "title": "ProposeRequest",
        "type": "object"
      },
      "PublishRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/dispatch/{date}/publish`, staff only: make a stored plan the record.\nChecked again against the day's stops; a repeat with the same `Idempotency-Key` publishes\nnothing more.",
        "properties": {
          "plan": {
            "$ref": "#/components/schemas/PlanChoice"
          }
        },
        "required": [
          "plan"
        ],
        "title": "PublishRequest",
        "type": "object"
      },
      "QuoteRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/catering/{cid}/quote`, staff only. `200` with the\n`CateringResponse`, now `quoted`; `409` problem of type `catering` naming the rule\n(`out-of-order`) once the inquiry is past `inquiry`; `422` `quote-total` for a total under 1\ncent.",
        "properties": {
          "total_cents": {
            "description": "A staff override of the total, in cents, at least 1. Absent: the package's price per\nhead times the headcount. The deposit is 25% of the total, rounded half-up.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "QuoteRequest",
        "type": "object"
      },
      "RebuildResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/rebuild`, which any session of the sandbox reads, and `202` from\n`POST` to it, staff only (a guest gets `403` `guest-scope`): \"Rebuild projections\" drops\nCrm's projections and replays its log, 200 events per alarm. A second `POST` (with a new\n`Idempotency-Key`) while one runs is `409` problem of type `rebuild` and starts nothing; the\nsame key again replays the first `202`. Nothing else is refused during a rebuild: other\ncommands run, reads answer the partial projection with `Projection-State: rebuilding`, and a\ncampaign send that falls due is deferred (logged as `sends_deferred`) until it ends. `GET`\nsays how far the running one is, and `finished` with its `ms` until the next start.",
        "properties": {
          "applied": {
            "description": "Log entries replayed so far.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "ms": {
            "description": "Once finished: the wall-clock milliseconds the rebuild took.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/RebuildState"
          },
          "total": {
            "description": "The log's length.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "state",
          "applied",
          "total"
        ],
        "title": "RebuildResponse",
        "type": "object"
      },
      "RebuildState": {
        "enum": [
          "idle",
          "rebuilding",
          "finished"
        ],
        "type": "string"
      },
      "RefundReason": {
        "description": "Why staff give money back: a choice from a list, never free text (docs/domain.md, \"Free\ntext and personal data\"). The other two reasons the domain knows, `cancelled` and\n`payment_late`, are the system's own.",
        "enum": [
          "missing_item",
          "quality",
          "goodwill"
        ],
        "type": "string"
      },
      "RefundRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/orders/{oid}/refund`, staff only. No `amount_cents` refunds all\nthat is left; refunding all that is left of an order not yet closed cancels it.",
        "properties": {
          "amount_cents": {
            "default": null,
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "reason": {
            "$ref": "#/components/schemas/RefundReason"
          }
        },
        "required": [
          "reason"
        ],
        "title": "RefundRequest",
        "type": "object"
      },
      "RefundResponse": {
        "additionalProperties": false,
        "description": "The answer to a refund request: accepted, and on its way to Stripe.",
        "properties": {
          "amount_cents": {
            "format": "int64",
            "type": "integer"
          },
          "refund": {
            "description": "The refund's ULID: the id of the order's `OrderRefundRequested` event, which Billing\nkeeps the refund under.",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus",
            "description": "The order's status after the request: unchanged for a part, `refund_pending` for the\nwhole of an order not yet closed."
          }
        },
        "required": [
          "refund",
          "amount_cents",
          "status"
        ],
        "title": "RefundResponse",
        "type": "object"
      },
      "ReminderKind": {
        "description": "A catering reminder: what it is for.",
        "oneOf": [
          {
            "const": "follow_up",
            "description": "3 business days after the quote, while it is still quoted.",
            "type": "string"
          },
          {
            "const": "event_soon",
            "description": "2 days before the event, while it is confirmed or in production.",
            "type": "string"
          },
          {
            "const": "invoice_due",
            "description": "When the balance invoice is 7 days old, while it is unpaid.",
            "type": "string"
          }
        ]
      },
      "SandboxKind": {
        "description": "Whose a sandbox is: a guest's, behind Turnstile, or a signed-in account's.",
        "enum": [
          "guest",
          "account"
        ],
        "type": "string"
      },
      "SandboxResponse": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes` (201 or 200) and `GET /v1/sandboxes/{id}`.",
        "properties": {
          "born": {
            "description": "A wall time.",
            "type": "string"
          },
          "children": {
            "description": "Registered child objects: the Catalog, the Kitchen and the 12 seeded orders once\nseeding is done, then one more for each order placed.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "clock_offset_s": {
            "description": "Business time minus wall time, in seconds (docs/architecture.md, \"Time travel\").",
            "format": "int64",
            "type": "integer"
          },
          "clock_v": {
            "description": "Bumped by every clock advance.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "faults": {
            "$ref": "#/components/schemas/Faults"
          },
          "id": {
            "description": "The sandbox's ULID.",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/SandboxKind"
          },
          "persona": {
            "description": "The visitor's customer persona: the seed's first customer's ULID. Orders the visitor\nplaces are this customer's.",
            "type": "string"
          },
          "persona_address": {
            "$ref": "#/components/schemas/PersonaAddress",
            "description": "The persona's synthetic address, from the seed: the Payment Element's billing address,\nso the visitor types none (ADR 0007, decision 6)."
          },
          "persona_name": {
            "description": "The persona's synthetic display name, from the seed: the Payment Element's billing name.",
            "type": "string"
          },
          "seed": {
            "description": "The seed the sandbox was generated from. A JSON number: JavaScript reads it exactly only\nbelow 2^53, so the router mints seeds in that range.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "state": {
            "$ref": "#/components/schemas/SandboxState"
          },
          "token_v": {
            "description": "Bumped by every API token rotation.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "wipe_at": {
            "description": "The first 10:00 UTC after `born`, a wall time.",
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "state",
          "born",
          "wipe_at",
          "seed",
          "persona",
          "persona_name",
          "persona_address",
          "clock_offset_s",
          "clock_v",
          "token_v",
          "faults",
          "children"
        ],
        "title": "SandboxResponse",
        "type": "object"
      },
      "SandboxState": {
        "description": "A sandbox's lifecycle (docs/domain.md, \"Sandbox\").",
        "oneOf": [
          {
            "enum": [
              "seeding",
              "live",
              "wiped"
            ],
            "type": "string"
          },
          {
            "const": "wiping",
            "description": "Every command gets 410 from here on.",
            "type": "string"
          }
        ]
      },
      "ScheduleRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/campaigns/{cid}/schedule`, staff only: `200` with the\n`CampaignResponse`, now `scheduled`. A `send_at` less than 15 minutes of business time after\nnow is `422` problem naming `schedule-too-soon`, its detail the earliest time allowed; a\ncampaign not in `draft` is `409` `campaign` naming `out-of-order`.\n`POST .../campaigns/{cid}/cancel` (no body) takes a scheduled campaign back to `draft` and a\ndraft to `cancelled`; a sent one is `409` `campaign` naming `out-of-order`.",
        "properties": {
          "send_at": {
            "description": "A business time, such as `2026-11-08T09:00:00-07:00`.",
            "type": "string"
          }
        },
        "required": [
          "send_at"
        ],
        "title": "ScheduleRequest",
        "type": "object"
      },
      "ScheduleResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/schedule/{date}`, and the answer to a capacity change: one bakery\nday's places, caps and bake list. It mirrors the Schedule aggregate's state.",
        "properties": {
          "bake_list": {
            "$ref": "#/components/schemas/BakeListView"
          },
          "catering": {
            "$ref": "#/components/schemas/CateringView"
          },
          "date": {
            "description": "The bakery day, `YYYY-MM-DD`.",
            "type": "string"
          },
          "items": {
            "description": "The items with a cap or a use that day, by slug; an item with no entry is uncapped.",
            "items": {
              "$ref": "#/components/schemas/ItemCapView"
            },
            "type": "array"
          },
          "menu_version": {
            "description": "The menu version the item caps came from; 0 before the first refresh.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "open": {
            "description": "Whether the bakery opens that day (Tuesday to Sunday); a closed day refuses every hold.",
            "type": "boolean"
          },
          "slots": {
            "description": "The 32 pickup slots, 07:00 to 14:45, in time order.",
            "items": {
              "$ref": "#/components/schemas/SlotView"
            },
            "type": "array"
          },
          "zones": {
            "description": "The three delivery zones, `z1` to `z3`.",
            "items": {
              "$ref": "#/components/schemas/ZoneView"
            },
            "type": "array"
          }
        },
        "required": [
          "date",
          "open",
          "slots",
          "zones",
          "items",
          "catering",
          "bake_list",
          "menu_version"
        ],
        "title": "ScheduleResponse",
        "type": "object"
      },
      "Segment": {
        "description": "A segment: a fixed rule over Crm's projection, evaluated at the business time asked.",
        "oneOf": [
          {
            "const": "everyone",
            "description": "Every persona.",
            "type": "string"
          },
          {
            "const": "cake-last-30-days",
            "description": "An order with a cake line in the last 30 days of business time.",
            "type": "string"
          },
          {
            "const": "delivery-customers",
            "description": "Any delivery order.",
            "type": "string"
          },
          {
            "const": "lapsed-60-days",
            "description": "No order in the last 60 days of business time.",
            "type": "string"
          },
          {
            "const": "catering-leads",
            "description": "A catering inquiry still open: an inquiry, a quote or an accepted quote.",
            "type": "string"
          }
        ]
      },
      "SegmentListResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/segments`: every segment, in the fixed order.",
        "properties": {
          "segments": {
            "items": {
              "$ref": "#/components/schemas/SegmentResponse"
            },
            "type": "array"
          }
        },
        "required": [
          "segments"
        ],
        "title": "SegmentListResponse",
        "type": "object"
      },
      "SegmentResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/segments/{segment}`: how many customers the rule holds now, and a\nfew of their ids. Consent is not applied here; a send applies it. An unknown segment is\n`404`.",
        "properties": {
          "members": {
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "sample": {
            "description": "Up to five member ULIDs, smallest first.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "segment": {
            "$ref": "#/components/schemas/Segment"
          }
        },
        "required": [
          "segment",
          "members",
          "sample"
        ],
        "title": "SegmentResponse",
        "type": "object"
      },
      "SessionKind": {
        "description": "How a session signed in. A guest has no account.",
        "enum": [
          "guest",
          "google",
          "github",
          "demo"
        ],
        "type": "string"
      },
      "SessionResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/session`, and the answer to a demo sign-in: what the cookie says, read without an\nobject call.",
        "properties": {
          "account": {
            "description": "The account id, 64 hex characters; `null` for a guest.",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "description": "When the cookie stops being accepted, a wall time such as `2026-11-05T12:00:00.000Z`.",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/SessionKind"
          },
          "sandbox": {
            "description": "The current sandbox's ULID, if any.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "kind",
          "expires_at"
        ],
        "title": "SessionResponse",
        "type": "object"
      },
      "SlotView": {
        "additionalProperties": false,
        "description": "One pickup slot of a day's schedule.",
        "properties": {
          "capacity": {
            "description": "Places in the slot.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "free": {
            "description": "`capacity` minus `taken`, 0 when over-booked after a capacity cut.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "start": {
            "description": "The slot's start, a business time such as `2026-07-14T14:45:00-06:00`.",
            "type": "string"
          },
          "taken": {
            "description": "Places held, reserved or fulfilled; released places do not count. Capped at 65,535.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "start",
          "capacity",
          "taken",
          "free"
        ],
        "type": "object"
      },
      "StatusCounters": {
        "additionalProperties": false,
        "description": "The status page's counters: the kept Analytics Engine queries over the last 24 hours, and\nthe last nightly wipe (docs/operations.md, \"Observability\"). Counts are sums of the points'\nsample intervals, so they stay counts when Analytics Engine samples.",
        "properties": {
          "dlq_24h": {
            "description": "`dlq` points in the last 24 hours: messages the dead-letter writer kept.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "last_wipe": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LastWipe"
              },
              {
                "type": "null"
              }
            ],
            "description": "The latest `wipe` point; `null` when none is in the dataset."
          },
          "orders_24h": {
            "description": "`order_placed` points in the last 24 hours.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "payment_failures_24h": {
            "description": "`payment_failed` points in the last 24 hours.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "payments_24h": {
            "description": "`payment_succeeded` points in the last 24 hours.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "refunds_24h": {
            "description": "`refund_issued` points in the last 24 hours.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "sandboxes_24h": {
            "description": "`sandbox_created` points in the last 24 hours, to read against the daily cap.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "orders_24h",
          "payments_24h",
          "payment_failures_24h",
          "refunds_24h",
          "sandboxes_24h",
          "dlq_24h",
          "last_wipe"
        ],
        "type": "object"
      },
      "StatusResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/status`: today's admission state, from the `Control` object.\n\nThe field order is fixed and is the wire order: the day and the sandbox count and cap\n(PR 2), then the guest and demo-account counts and caps (PR 3), then the status page's\ncounters with their time and state (PR 13), then the breaker's state (PR 17), then the flag.\nReaders go by name, so PR 2's smoke check still passes; a new field is added before `flag`.\n\nThe counters are a snapshot of the kept Analytics Engine queries that the 15-minute cron\nrefreshes, never a query per request (docs/operations.md, \"Observability\").",
        "properties": {
          "breaker": {
            "$ref": "#/components/schemas/BreakerStatus",
            "description": "The 15-minute cron breaker's state and its last run, kept in `Control`."
          },
          "counters": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StatusCounters"
              },
              {
                "type": "null"
              }
            ],
            "description": "The last snapshot of the kept queries; `null` until the first refresh succeeds."
          },
          "counters_as_of": {
            "description": "When that snapshot was taken, an RFC 3339 UTC time such as `2026-11-06T10:15:02.114Z`;\n`null` with `counters`.",
            "type": [
              "string",
              "null"
            ]
          },
          "counters_state": {
            "$ref": "#/components/schemas/CountersState",
            "description": "Whether the counters are fresh: `live`, `stale` or `unavailable`."
          },
          "day": {
            "description": "Today's UTC date, `YYYY-MM-DD`: the key of the daily ledger.",
            "type": "string"
          },
          "demo_account_cap": {
            "description": "The most demo accounts created in one UTC day.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "demo_accounts_today": {
            "description": "Demo accounts created today.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "flag": {
            "$ref": "#/components/schemas/Flag",
            "description": "The demo's flag."
          },
          "guest_cap": {
            "description": "The guests' share of the day's sandboxes.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "guests_today": {
            "description": "Guest sandboxes admitted today.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "sandbox_cap": {
            "description": "The most sandboxes admitted in one UTC day.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "sandboxes_today": {
            "description": "Sandboxes admitted today, guests' included.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "day",
          "sandboxes_today",
          "sandbox_cap",
          "guests_today",
          "guest_cap",
          "demo_accounts_today",
          "demo_account_cap",
          "counters_state",
          "breaker",
          "flag",
          "counters",
          "counters_as_of"
        ],
        "title": "StatusResponse",
        "type": "object"
      },
      "StopStatus": {
        "description": "Where a delivery stop stands (ADR 0012; docs/domain.md, \"Ubiquitous language\": Stop).",
        "oneOf": [
          {
            "const": "provisional",
            "description": "Placed, not yet paid: shown, in no plan.",
            "type": "string"
          },
          {
            "const": "confirmed",
            "description": "Paid: every plan must carry it.",
            "type": "string"
          },
          {
            "const": "removed",
            "description": "Expired or cancelled.",
            "type": "string"
          },
          {
            "const": "completed",
            "description": "Delivered.",
            "type": "string"
          }
        ]
      },
      "StopView": {
        "additionalProperties": false,
        "description": "One stop of the day.",
        "properties": {
          "customer": {
            "description": "The customer's ULID; the screen shows the persona's made-up address, never the place.",
            "type": "string"
          },
          "order": {
            "description": "The order's ULID: what every plan names the stop by.",
            "type": "string"
          },
          "place": {
            "description": "The customer's place, an index into the travel-time matrix, 0 to 63.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          },
          "place_label": {
            "description": "The place's label, `p1` to `p64`.",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/StopStatus"
          },
          "stop": {
            "description": "The stop's number in the published plan, counted from 1 across the vans, van 1's stops\nfirst; `null` when it is in no published plan.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "units": {
            "description": "The order's line quantities summed: what the stop takes of a van's capacity.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "van": {
            "description": "The van that carries it in the published plan; `null` when none does.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "window": {
            "description": "The delivery window's start, a business time (RFC 3339 with the bakery's offset). The\nwindow is 2 hours long: it closes 120 minutes after this. A plan must reach the stop\nbetween the two, waiting at the door when it is early (rule `window`).",
            "type": "string"
          },
          "zone": {
            "description": "`z1`, `z2` or `z3`.",
            "type": "string"
          }
        },
        "required": [
          "order",
          "customer",
          "place",
          "place_label",
          "window",
          "zone",
          "units",
          "status"
        ],
        "type": "object"
      },
      "SubjectTemplate": {
        "description": "A campaign's subject, chosen from a fixed list; staff never type one (Q14).",
        "enum": [
          "weekend-bake",
          "cake-week",
          "new-season",
          "we-miss-you",
          "catering-season",
          "thank-you"
        ],
        "type": "string"
      },
      "TimelineEntry": {
        "additionalProperties": false,
        "description": "One line of a timeline.",
        "properties": {
          "at": {
            "description": "The event's business time.",
            "type": "string"
          },
          "label": {
            "description": "A short fixed sentence with the event's own figures, such as `Paid $22.00`.",
            "type": "string"
          },
          "ref": {
            "description": "The ULID of the order, catering event, message or customer the line is about.",
            "type": "string"
          },
          "type": {
            "description": "The event's catalog name, such as `OrderPaid`.",
            "type": "string"
          }
        },
        "required": [
          "at",
          "type",
          "ref",
          "label"
        ],
        "type": "object"
      },
      "TimelineResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/customers/{cid}/timeline`: the customer's events in business-time\norder. While a rebuild runs the timeline is partial; `GET .../rebuild` says so.",
        "properties": {
          "customer": {
            "type": "string"
          },
          "entries": {
            "items": {
              "$ref": "#/components/schemas/TimelineEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "customer",
          "entries"
        ],
        "title": "TimelineResponse",
        "type": "object"
      },
      "TokenInfoResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/token`: what the console shows about the token without the token.",
        "properties": {
          "expires_at": {
            "description": "When that token stops being accepted, a wall time.",
            "type": [
              "string",
              "null"
            ]
          },
          "issued_at": {
            "description": "When the last token at this version was issued, a wall time; absent before the first\nissue and after a rotation until the next.",
            "type": [
              "string",
              "null"
            ]
          },
          "masked": {
            "description": "That token's first 6 and last 4 characters around `…`, such as `eyJ2Ij…x7Qk`: enough\nto tell two tokens apart, never enough to use one.",
            "type": [
              "string",
              "null"
            ]
          },
          "token_v": {
            "description": "The Sandbox's token version: a token naming an older one is refused.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "token_v"
        ],
        "title": "TokenInfoResponse",
        "type": "object"
      },
      "TokenResponse": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/token` (issue, or issue again at the same version) and\n`POST /v1/sandboxes/{id}/token/rotate` (the Sandbox's token version goes up, `ApiTokenRotated`\nis appended, and every token naming an older version stops at once): the token, shown this\nonce. It is never stored, logged, put in an event or printed by this type's `Debug`; the\nconsole holds it in memory to copy it.",
        "properties": {
          "expires_at": {
            "description": "24 h after `issued_at`, a wall time; the sandbox's wipe ends it sooner.",
            "type": "string"
          },
          "issued_at": {
            "description": "A wall time, such as `2026-11-05T12:00:00.000Z`.",
            "type": "string"
          },
          "token": {
            "description": "For `Authorization: Bearer <token>`: `<payload>.<mac>`, both base64url, signed like the\nsession cookie. Never in a URL: a token in a query string is refused with 400.",
            "type": "string"
          },
          "token_v": {
            "description": "The Sandbox's token version the token names.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "token",
          "token_v",
          "issued_at",
          "expires_at"
        ],
        "title": "TokenResponse",
        "type": "object"
      },
      "TrafficRequest": {
        "additionalProperties": false,
        "description": "`POST /v1/sandboxes/{id}/traffic`, signed-in sessions only: simulated orders a minute.",
        "properties": {
          "rate": {
            "description": "1 to 6.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "rate"
        ],
        "title": "TrafficRequest",
        "type": "object"
      },
      "TrafficResponse": {
        "additionalProperties": false,
        "description": "`GET /v1/sandboxes/{id}/traffic`, and the answer to starting or stopping it.",
        "properties": {
          "minutes_left": {
            "description": "What is left of the day's cap, 30 minutes (docs/cost.md, \"Guardrails\").",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "minutes_used": {
            "description": "Minutes of traffic this sandbox used today, UTC.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "orders": {
            "description": "Orders the simulator placed today.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "rate": {
            "description": "Orders a minute of the current or last run; 0 before the first start.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          },
          "running": {
            "type": "boolean"
          }
        },
        "required": [
          "running",
          "rate",
          "minutes_used",
          "minutes_left",
          "orders"
        ],
        "title": "TrafficResponse",
        "type": "object"
      },
      "VanPlanView": {
        "additionalProperties": false,
        "description": "One van of a plan.",
        "properties": {
          "minutes": {
            "description": "The drive, bakery to bakery, from the travel-time matrix.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "stops": {
            "description": "Order ULIDs, in driving order.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "units": {
            "description": "The stops' units summed; never over the day's capacity.",
            "format": "uint32",
            "minimum": 0,
            "type": "integer"
          },
          "van": {
            "description": "1 to the day's vans.",
            "format": "uint8",
            "maximum": 255,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "van",
          "stops",
          "units",
          "minutes"
        ],
        "type": "object"
      },
      "WipedResponse": {
        "additionalProperties": false,
        "description": "`DELETE /v1/sandboxes/{id}`, \"Wipe now\": the sandbox is gone when this answers.",
        "properties": {
          "id": {
            "type": "string"
          },
          "state": {
            "$ref": "#/components/schemas/SandboxState",
            "description": "Always `wiped`."
          }
        },
        "required": [
          "id",
          "state"
        ],
        "title": "WipedResponse",
        "type": "object"
      },
      "ZoneView": {
        "additionalProperties": false,
        "description": "One delivery zone of a day's schedule. A zone's stops are shared by its three windows.",
        "properties": {
          "capacity": {
            "description": "Stops in the zone for the day.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "free": {
            "description": "`capacity` minus `taken`, 0 when over-booked.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "taken": {
            "description": "Stops held, reserved or fulfilled.",
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "windows": {
            "description": "The zone's window starts, 09:00, 11:00 and 13:00, business times.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "zone": {
            "description": "`z1`, `z2` or `z3`.",
            "type": "string"
          }
        },
        "required": [
          "zone",
          "capacity",
          "taken",
          "free",
          "windows"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearerToken": {
        "bearerFormat": "bakery API token",
        "description": "The sandbox's API token, signed like the session cookie, 24 h, dying with the sandbox and with every rotation. In `Authorization: Bearer` only: a token in a query string, or a token and a cookie together, is 400 `token`. Rate-limited per token.",
        "scheme": "bearer",
        "type": "http"
      },
      "sessionCookie": {
        "description": "The session cookie: HttpOnly, Secure, SameSite=Strict, host-only on the API, 24 h. A request carrying it must send the storefront's exact `Origin` on every POST, PATCH and DELETE and on the socket's upgrade.",
        "in": "cookie",
        "name": "__Host-session",
        "type": "apiKey"
      },
      "stripeSignature": {
        "description": "Stripe's signature over the raw body, with the endpoint secret. Only Stripe calls the webhook.",
        "in": "header",
        "name": "Stripe-Signature",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "Every console action has a call here. Every bakery is a private sandbox of synthetic data, wiped at the next 10:00 UTC. From a browser, the `__Host-session` cookie carries the session; from anywhere else, the sandbox's API token goes in `Authorization: Bearer` (signed-in sandboxes only; issue it in the console or with `POST /v1/sandboxes/{id}/token`). A request with a token and no cookie needs no `Origin`. Every `POST` carries an `Idempotency-Key`, a ULID; the same key again gets the first answer with `Idempotent-Replayed: true`. Every error is `application/problem+json` (RFC 9457), its `type` `https://bakery.ihaveasegway.com/problems/<slug>`. Money is integer US cents; business times carry the bakery's Mountain offset, wall times are UTC with `Z`. Generated from crates/contracts: the route table and the schemas.",
    "license": {
      "identifier": "MIT",
      "name": "MIT"
    },
    "summary": "The API the bakery's console calls, and a visitor's own client can too.",
    "title": "Proof of Concept Bakery API",
    "version": "1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/auth/demo": {
      "post": {
        "description": "Anyone; a session, if present, is read but not required. Carries an `Idempotency-Key`.",
        "operationId": "demo-signup",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DemoSignupRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DemoSignupResponse"
                }
              }
            },
            "description": "the generated username, and the cookie",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON",
            "x-problems": [
              "idempotency-key",
              "body"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`turnstile`: Turnstile refused the token; `origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "turnstile",
              "origin"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`password`: 12 to 128 characters; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "password",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`demo-cap`: the day's demo accounts are used up",
            "x-problems": [
              "demo-cap"
            ]
          }
        },
        "security": [
          {},
          {
            "sessionCookie": []
          }
        ],
        "summary": "Create a demo account behind Turnstile; the username is shown once",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/auth/demo/signin": {
      "post": {
        "description": "Anyone; a session, if present, is read but not required. Carries an `Idempotency-Key`.",
        "operationId": "demo-signin",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DemoSigninRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            },
            "description": "the session, and the cookie",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON",
            "x-problems": [
              "idempotency-key",
              "body"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`credentials`: no such username, or the wrong password",
            "x-problems": [
              "credentials"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`locked`: 10 failures in 15 minutes; with `Retry-After`; `rate-limit`: the session's or IP hash's limit, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "locked",
              "rate-limit"
            ]
          }
        },
        "security": [
          {},
          {
            "sessionCookie": []
          }
        ],
        "summary": "Sign in to a demo account",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/auth/github/callback": {
      "get": {
        "description": "Anyone.",
        "operationId": "github-callback",
        "parameters": [
          {
            "description": "GitHub's authorization code",
            "in": "query",
            "name": "code",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "the value `__Host-oauth` holds",
            "in": "query",
            "name": "state",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "303": {
            "description": "to the storefront's path, setting `__Host-session`; to `/signin/?error=state`, `exchange`, `token`, `provider` or `oauth`",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          }
        },
        "security": [],
        "summary": "GitHub's redirect back: the numeric user id is all it keeps",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/auth/github/start": {
      "get": {
        "description": "Anyone.",
        "operationId": "github-start",
        "parameters": [
          {
            "description": "the storefront path to come back to, such as `/app/`",
            "in": "query",
            "name": "return",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "to GitHub with no `scope` parameter; sets `__Host-oauth`",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          }
        },
        "security": [],
        "summary": "Start a GitHub sign-in",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/auth/google/callback": {
      "get": {
        "description": "Anyone.",
        "operationId": "google-callback",
        "parameters": [
          {
            "description": "Google's authorization code",
            "in": "query",
            "name": "code",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "the value `__Host-oauth` holds",
            "in": "query",
            "name": "state",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "303": {
            "description": "to the storefront's path, setting `__Host-session`; to `/signin/?error=state`, `exchange`, `token`, `provider` or `oauth`",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          }
        },
        "security": [],
        "summary": "Google's redirect back: the `__Host-oauth` cookie and `state` are the check",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/auth/google/start": {
      "get": {
        "description": "Anyone.",
        "operationId": "google-start",
        "parameters": [
          {
            "description": "the storefront path to come back to, such as `/app/`",
            "in": "query",
            "name": "return",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "to Google with `scope=openid` alone; sets `__Host-oauth`",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          }
        },
        "security": [],
        "summary": "Start a Google sign-in",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/auth/signout": {
      "post": {
        "description": "Any session, a guest's included. Carries an `Idempotency-Key`.",
        "operationId": "signout",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "the cookie cleared",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: an API token: this route takes the session cookie only (`cookie-only`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "summary": "Sign out: the cookie is cleared and an account's session id revoked",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "any"
      }
    },
    "/v1/health": {
      "get": {
        "description": "Anyone.",
        "operationId": "health",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            },
            "description": "`{status, commit, version}`; touches no object"
          }
        },
        "security": [],
        "summary": "The Worker answers, and which build it is",
        "tags": [
          "service"
        ],
        "x-pr": 2,
        "x-session": "public"
      }
    },
    "/v1/sandboxes": {
      "post": {
        "description": "Anyone; a session, if present, is read but not required. Carries an `Idempotency-Key`.",
        "operationId": "create-sandbox",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSandboxRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxResponse"
                }
              }
            },
            "description": "an account's live sandbox, unless `replace`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxResponse"
                }
              }
            },
            "description": "a new sandbox; the cookie is re-issued with `sbx`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON",
            "x-problems": [
              "idempotency-key",
              "body"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`turnstile`: a guest without a good Turnstile token; `origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "turnstile",
              "origin"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: this IP hash's creations this minute; `account-sandbox-cap`: 3 sandboxes an account a day",
            "x-problems": [
              "rate-limit",
              "account-sandbox-cap"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`sandbox-cap`: 300 sandboxes a UTC day; `guest-cap`: 100 guest sandboxes a UTC day; `read-only`: the demo's flag is read-only; `off`: the demo's flag is off",
            "x-problems": [
              "sandbox-cap",
              "guest-cap",
              "read-only",
              "off"
            ]
          }
        },
        "security": [
          {},
          {
            "sessionCookie": []
          }
        ],
        "summary": "A sandbox: Turnstile for a guest, admitted by Control, seeded",
        "tags": [
          "sandbox"
        ],
        "x-pr": 3,
        "x-session": "public"
      }
    },
    "/v1/sandboxes/{id}": {
      "delete": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "wipe-sandbox",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WipedResponse"
                }
              }
            },
            "description": "`{id, state: wiped}`; an account's cookie loses `sbx`, a guest's is cleared"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Wipe now, finished in the request",
        "tags": [
          "sandbox"
        ],
        "x-pr": 3,
        "x-session": "sandbox"
      },
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-sandbox",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxResponse"
                }
              }
            },
            "description": "the Sandbox's state"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The sandbox's state",
        "tags": [
          "sandbox"
        ],
        "x-pr": 3,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/activity": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-activity",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "how many entries",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityResponse"
                }
              }
            },
            "description": "the activity feed"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The sandbox's logged events, newest first",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/billing/ledger": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "ledger",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LedgerResponse"
                }
              }
            },
            "description": "the ledger"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`stripe-key`: the API has no sandbox Stripe key",
            "x-problems": [
              "stripe-key"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Every payment and refund Billing recorded, and the totals",
        "tags": [
          "payments"
        ],
        "x-pr": 5,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/campaigns": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "list-campaigns",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignListResponse"
                }
              }
            },
            "description": "the campaigns"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Every campaign, by id",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      },
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "create-campaign",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignResponse"
                }
              }
            },
            "description": "the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignResponse"
                }
              }
            },
            "description": "the draft, with `Location`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "A draft campaign, from the fixed templates",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/campaigns/{cid}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-campaign",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignResponse"
                }
              }
            },
            "description": "the campaign"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown campaign"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One campaign",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      },
      "patch": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie.",
        "operationId": "edit-campaign",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyOptional"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignResponse"
                }
              }
            },
            "description": "the draft; the same optional `Idempotency-Key` again replays it"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown campaign"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`campaign`: `out-of-order`: scheduled, sent or cancelled",
            "x-problems": [
              "campaign"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Edit a draft campaign",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/campaigns/{cid}/cancel": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "cancel-campaign",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignResponse"
                }
              }
            },
            "description": "the campaign",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown campaign"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`campaign`: `out-of-order`: already sent",
            "x-problems": [
              "campaign"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "A scheduled campaign back to draft, or a draft cancelled",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/campaigns/{cid}/schedule": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "schedule-campaign",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignResponse"
                }
              }
            },
            "description": "`scheduled`; the same key again replays it",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown campaign"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`campaign`: `out-of-order`: not a draft",
            "x-problems": [
              "campaign"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`campaign`: `schedule-too-soon`, its detail the earliest time allowed; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "campaign",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Schedule a draft; the send is the object's timer, never a route",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/catering": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "list-catering",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringListResponse"
                }
              }
            },
            "description": "the events, the seeded eight included"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Every registered catering event, newest inquiry first",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      },
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "create-catering",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CateringInquiryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "the inquiry, with `Location`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: `detail` ends `The rule is <slug>.`; never echoes the brief; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "catering",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "A catering inquiry, as the sandbox's persona",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-catering",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "the event"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an id this sandbox has not registered, another's included"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One catering event, with the reminders still to come",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/accept": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "accept-quote",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`accepted`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`slot-full`: both of the day's catering places are taken; nothing recorded; `catering`: `out-of-order` or `quote-expired`",
            "x-problems": [
              "slot-full",
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Accept the quote: the day's catering place is held while the deposit is paid",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/cancel": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "cancel-catering",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CateringCancelRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`cancelled`, with `refund_deposit`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: `out-of-order`",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The customer cancels a confirmed event; more than 7 days out the deposit is refunded",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/decline": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "decline-catering",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeclineRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`declined`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: past `inquiry`",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Staff decline an inquiry",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/delivered": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "mark-catering-delivered",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`delivered`; poll for `invoice`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: `out-of-order`; `too-early` before the event day",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Staff mark it delivered; Billing raises the balance invoice",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/deposit": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "catering-deposit",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentResponse"
                }
              }
            },
            "description": "the payment and its one-time `client_secret`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: unless accepted",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`stripe-key`: the API has no sandbox Stripe key",
            "x-problems": [
              "stripe-key"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The deposit's payment, 25% of the quote, as an order's `/payment`",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/pay-balance": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "pay-balance",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "the event as it stands: poll until `closed`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: unless invoiced",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Pay the balance invoice on Stripe's test path; the webhook closes the event",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/quote": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "send-quote",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`quoted`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: `out-of-order`, or `quote-expired` once the day before the event has begun",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: `quote-total`, a total under 1 cent; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "catering",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Staff quote an inquiry",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/staff-cancel": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "staff-cancel-catering",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CateringCancelRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`cancelled`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: out of order",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Staff cancel a confirmed event",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/catering/{cid}/start-production": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "start-catering-production",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CateringResponse"
                }
              }
            },
            "description": "`in_production`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`catering`: `out-of-order` unless confirmed; `too-early` before the day before the event",
            "x-problems": [
              "catering"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Staff start production of a confirmed event",
        "tags": [
          "catering"
        ],
        "x-pr": 7,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/clock": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "advance-clock",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClockRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClockResponse"
                }
              }
            },
            "description": "the clock, with `step`; the same key again: the first answer, and nothing moves again",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`clock`: naming `offset-cap` or `not-positive` (also for both or neither); `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "clock",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Move business time forward, at most 14 days in all",
        "tags": [
          "sandbox"
        ],
        "x-pr": 4,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/customers": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "list-customers",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerListResponse"
                }
              }
            },
            "description": "the customers, by id"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The sandbox's 60 synthetic customers",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/customers/{cid}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-customer",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponse"
                }
              }
            },
            "description": "the customer"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown customer"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One customer as Crm's projection holds it",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/customers/{cid}/consent": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "set-consent",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConsentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponse"
                }
              }
            },
            "description": "the customer; the same `Idempotency-Key` again replays it, with `Idempotent-Replayed`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`guest-scope`: a guest changing another persona's consent; `origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "guest-scope",
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown customer"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Marketing consent, by the customer's own persona or by staff",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/customers/{cid}/timeline": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-timeline",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A catering event's, a customer's or a campaign's ULID, as the path says.",
            "in": "path",
            "name": "cid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimelineResponse"
                }
              }
            },
            "description": "the timeline; partial while a rebuild runs"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown customer"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "A customer's events in business-time order",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/dead-letters": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "list-dead-letters",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/DeadLetter"
                  },
                  "type": "array"
                }
              }
            },
            "description": "an array of dead letters"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The messages the Queue gave up on, oldest first",
        "tags": [
          "sandbox"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/dead-letters/{eventId}/redrive": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "redrive",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The dead-lettered event's ULID.",
            "in": "path",
            "name": "eventId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeadLetter"
                }
              }
            },
            "description": "the dead letter sent again, its row removed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an id this sandbox has not registered, another's included"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Send a dead letter again with its own id",
        "tags": [
          "sandbox"
        ],
        "x-pr": 4,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/dispatch/{date}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-dispatch",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchResponse"
                }
              }
            },
            "description": "the day"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One bakery day's delivery stops and plans",
        "tags": [
          "dispatch"
        ],
        "x-pr": 9,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/dispatch/{date}/complete": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "complete-stop",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteStopRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchResponse"
                }
              }
            },
            "description": "the day; again for a delivered stop changes nothing",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`dispatch`: `no-plan`, or `not-ready` (the stop's order is not ready yet)",
            "x-problems": [
              "dispatch"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`dispatch`: `stop-unknown`; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "dispatch",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "A stop of the published plan is delivered",
        "tags": [
          "dispatch"
        ],
        "x-pr": 9,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/dispatch/{date}/plan": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "submit-plan",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchResponse"
                }
              }
            },
            "description": "the day, with `submitted` and `comparison`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`dispatch`: `route-ends`, `vans`, `stop-unknown`, `stop-twice`, `over-capacity`, `stop-missing`, `window` (a stop reached after its delivery window closes) or `no-stops`; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "dispatch",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The plan VROOM made in the browser; the server computes its minutes",
        "tags": [
          "dispatch"
        ],
        "x-pr": 9,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/dispatch/{date}/propose": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "propose-dispatch",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProposeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchResponse"
                }
              }
            },
            "description": "the day, with `proposed`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`dispatch`: `vans`, `capacity`, `no-stops` or `place-unknown`; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "dispatch",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The server's savings plan for the confirmed stops",
        "tags": [
          "dispatch"
        ],
        "x-pr": 9,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/dispatch/{date}/publish": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "publish-dispatch",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchResponse"
                }
              }
            },
            "description": "the day, with `published`; the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`dispatch`: `no-plan`, `stop-missing`, `published` (a van has left) or the plan's own rules again",
            "x-problems": [
              "dispatch"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Make a stored plan the record",
        "tags": [
          "dispatch"
        ],
        "x-pr": 9,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/faults": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "set-fault",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FaultRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FaultsResponse"
                }
              }
            },
            "description": "every switch as it now stands",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Switch the Kitchen's or the Inbox's broken-subscriber fault",
        "tags": [
          "sandbox"
        ],
        "x-pr": 3,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/heartbeat": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "heartbeat",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "204": {
            "description": "noted",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The console is open with no socket: the Kitchen keeps the time for the Simulator",
        "tags": [
          "kitchen"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/inbox": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "list-inbox",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "one message kind, such as `receipt`",
            "in": "query",
            "name": "kind",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "one customer's ULID",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "how many, 50 when left out",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboxResponse"
                }
              }
            },
            "description": "the messages and the filters' total"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`filter`: a filter the inbox refuses; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "filter",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The sandbox's inbox, newest first",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/inbox/{mid}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-message",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A message's ULID.",
            "in": "path",
            "name": "mid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            },
            "description": "the message"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown message"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One message, with its opens and clicks as the Inbox simulated them",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/kitchen/ws": {
      "get": {
        "description": "A session of sandbox `{id}`, by the cookie only, with the storefront's exact `Origin`.",
        "operationId": "kitchen-socket",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "the socket; frames in `x-websocket`"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: an API token: this route takes the session cookie only (`cookie-only`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "426": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`upgrade`: without `Upgrade: websocket`",
            "x-problems": [
              "upgrade"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "summary": "The kitchen board's socket, protocol v1 (`x-websocket`)",
        "tags": [
          "kitchen"
        ],
        "x-pr": 4,
        "x-session": "cookie",
        "x-websocket": {
          "description": "Frames are JSON text, each with `\"v\": 1`. Limits: 4 open sockets a sandbox (a fifth is told `bye` `limit` and closed with 1008), frames of at most 4 KB (1009), 10 frames a second a socket (1008), text frames only (1003). The storefront sends no ping and reconnects instead.",
          "frames": [
            {
              "direction": "server-to-client",
              "shape": "{t: \"snapshot\", v: 1, board: {cards, bake_lists}, seq}",
              "t": "snapshot",
              "when": "on open; `seq` counts the events that changed the board; `bake_lists` is one entry per bakery day from business today on, `[{date, version, lines: [{item, qty, start, catering?}], reserved}]`, `catering: true` on a catering event's line, whose `qty` is its headcount"
            },
            {
              "direction": "server-to-client",
              "shape": "{t: \"evt\", v: 1, env, bake_list?}",
              "t": "evt",
              "when": "each event that changed the board, the envelope whole, the note with it; and the Sandbox's `ClockAdvanced`. A `BakeListChanged`, `SlotReserved` or `SlotReleased` frame also carries `bake_list`, that day as the board holds it after the event, `{date, version, lines: [{item, qty, start, catering?}], reserved}` (since 2026-11-06; `catering` since 2026-11-08): set the day from it, do not adjust a count"
            },
            {
              "direction": "server-to-client",
              "shape": "{t: \"presence\", v: 1, sockets}",
              "t": "presence",
              "when": "a socket opened or closed"
            },
            {
              "direction": "server-to-client",
              "shape": "{t: \"bye\", v: 1, reason: \"wiped\" | \"limit\"}",
              "t": "bye",
              "when": "before the server closes: 1001 at the wipe; 1008, 1009 or 1003 at a limit"
            },
            {
              "direction": "client-to-server",
              "shape": "{t: \"cmd\", v: 1, id: <ULID>, order: <ULID>, action: \"start_production\" | \"mark_ready\" | \"mark_picked_up\"}",
              "t": "cmd",
              "when": "a staff action, sent to the Order with `id` as the idempotency key"
            },
            {
              "direction": "server-to-client",
              "shape": "{t: \"ack\", v: 1, id}",
              "t": "ack",
              "when": "the command was applied; a repeated `id` gets the first answer"
            },
            {
              "direction": "server-to-client",
              "shape": "{t: \"nack\", v: 1, id, rule}",
              "t": "nack",
              "when": "the command was refused, naming the rule; a guest gets `guest-scope`"
            },
            {
              "direction": "client-to-server",
              "shape": "{t: \"ping\", v: 1}",
              "t": "ping",
              "when": "answered `{t: \"pong\", v: 1}` by the platform's auto-response, which does not wake the object"
            },
            {
              "direction": "server-to-client",
              "shape": "{t: \"pong\", v: 1}",
              "t": "pong",
              "when": "the answer to a `ping`"
            }
          ],
          "protocol": "v1"
        }
      }
    },
    "/v1/sandboxes/{id}/leads": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-leads",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadPipelineResponse"
                }
              }
            },
            "description": "every stage, in order"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The catering lead pipeline, by stage",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/menu": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-menu",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuResponse"
                }
              }
            },
            "description": "the Catalog's published menu"
          },
          "304": {
            "description": "a matching `If-None-Match`"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The published menu, with `ETag: \"v<n>\"`",
        "tags": [
          "menu"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/menu/drafts": {
      "get": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-menu-drafts",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuDraftsResponse"
                }
              }
            },
            "description": "`{version, pending}`: the published version and each pending item's draft, in slug order"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The items with drafts waiting for a publish, as their draft copies stand",
        "tags": [
          "menu"
        ],
        "x-pr": 19,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/menu/items/{slug}": {
      "patch": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie.",
        "operationId": "patch-menu-item",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A menu item's slug, such as `croissant`.",
            "in": "path",
            "name": "slug",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyOptional"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MenuItemPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuEditResponse"
                }
              }
            },
            "description": "`{version, pending}`"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "no such item"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`menu`: the rule is named in `detail`",
            "x-problems": [
              "menu"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "A draft price on every variant, or a pause or resume published at once",
        "tags": [
          "menu"
        ],
        "x-pr": 4,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/menu/publish": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "publish-menu",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MenuEditResponse"
                }
              }
            },
            "description": "`{version, pending}`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`menu`: no drafts to publish; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "menu",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Publish the drafts: `MenuPublished`, the version plus one",
        "tags": [
          "menu"
        ],
        "x-pr": 4,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/orders": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "place-order",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "the order, with `Location`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`slot-full`: with `next_free`, the next free start that day; `item-cap`: an item's daily cap is reached; `lead-time`: naming the hours, such as a 48 h cake for tomorrow; `hold-lost`: a retry whose place was given back before any order was placed, with no room left; with `next_free`",
            "x-problems": [
              "slot-full",
              "item-cap",
              "lead-time",
              "hold-lost"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-slot`: not a slot or window start, or a day outside the sandbox's; `closed-day`: the bakery is closed that day; `order`: naming the rule (`note-<class>` for the note); `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "no-such-slot",
              "closed-day",
              "order",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Place an order as the sandbox's persona; its slot is held until it is paid",
        "tags": [
          "orders"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/orders/{oid}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-order",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "An order's ULID.",
            "in": "path",
            "name": "oid",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "the order"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an id this sandbox has not registered, another's included"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One order, once the Sandbox's registry holds it",
        "tags": [
          "orders"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/orders/{oid}/cancel": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "cancel-order",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "An order's ULID.",
            "in": "path",
            "name": "oid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            },
            "description": "the order, cancelled",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an id this sandbox has not registered, another's included"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`order`: naming the rule; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "order",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The customer cancels",
        "tags": [
          "orders"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/orders/{oid}/payment": {
      "post": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "pay",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "An order's ULID.",
            "in": "path",
            "name": "oid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentResponse"
                }
              }
            },
            "description": "the payment and its one-time `client_secret`",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`",
            "x-problems": [
              "origin"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown order"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`order`: unless the order is `placed`",
            "x-problems": [
              "order"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`stripe-key`: the API has no sandbox Stripe key",
            "x-problems": [
              "stripe-key"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "What the browser needs to mount Stripe's Payment Element; only the webhook marks it paid",
        "tags": [
          "orders"
        ],
        "x-pr": 5,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/orders/{oid}/refund": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "refund",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "An order's ULID.",
            "in": "path",
            "name": "oid",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefundRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundResponse"
                }
              }
            },
            "description": "the refund, on its way to Stripe; the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`order`: `no-stripe-payment`: a seeded order Stripe never charged",
            "x-problems": [
              "order"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`order`: `refund-exceeds-paid` or `out-of-order`; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "order",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`stripe-key`: the API has no sandbox Stripe key",
            "x-problems": [
              "stripe-key"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Staff refund a part or all that is left; Billing refunds at Stripe from the Queue",
        "tags": [
          "orders"
        ],
        "x-pr": 5,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/rebuild": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-rebuild",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RebuildResponse"
                }
              }
            },
            "description": "the cursor"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The rebuild's progress; ask every second while `rebuilding`",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      },
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "start-rebuild",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RebuildResponse"
                }
              }
            },
            "description": "the rebuild, started",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rebuild`: a second start while one is running; other commands still run",
            "x-problems": [
              "rebuild"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Rebuild projections: drop Crm's projections and replay its log",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/schedule/{date}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-schedule",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            },
            "description": "the day"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`seeding`: the sandbox is still being seeded",
            "x-problems": [
              "seeding"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "One bakery day: slots, zones, item caps, catering and the bake list",
        "tags": [
          "schedule"
        ],
        "x-pr": 6,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/schedule/{date}/capacity": {
      "patch": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie.",
        "operationId": "set-capacity",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A bakery day, `YYYY-MM-DD`.",
            "in": "path",
            "name": "date",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyOptional"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CapacityRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleResponse"
                }
              }
            },
            "description": "the day"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`no-such-day`: a date outside the sandbox's days",
            "x-problems": [
              "no-such-day"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`bad-target`: not `slot:HH:MM`, `zone:z1` to `z3`, `item:<slug>` or `catering`; `unknown-item`: an `item:<slug>` the day's published menu does not list",
            "x-problems": [
              "bad-target",
              "unknown-item"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Set one capacity for the day; places already taken stay",
        "tags": [
          "schedule"
        ],
        "x-pr": 6,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/segments": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "list-segments",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SegmentListResponse"
                }
              }
            },
            "description": "the five segments, in the fixed order"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Every segment, with its member count and a sample",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/segments/{segment}": {
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-segment",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A segment's slug, such as `lapsed-60-days`.",
            "in": "path",
            "name": "segment",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SegmentResponse"
                }
              }
            },
            "description": "the segment"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "an unknown segment"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "How many customers a segment holds now",
        "tags": [
          "crm"
        ],
        "x-pr": 8,
        "x-session": "sandbox"
      }
    },
    "/v1/sandboxes/{id}/token": {
      "get": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-token",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenInfoResponse"
                }
              }
            },
            "description": "the token's info"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The token's version and times, and the last issued one masked; never the token",
        "tags": [
          "token"
        ],
        "x-pr": 10,
        "x-session": "signed-in"
      },
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The cookie only: an API token never mints its successor. Carries an `Idempotency-Key`.",
        "operationId": "issue-token",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "description": "the token, shown once; the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: an API token: this route takes the session cookie only (`cookie-only`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "summary": "Issue the sandbox's API token at its current version, or issue it again; shown once",
        "tags": [
          "token"
        ],
        "x-pr": 10,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/token/rotate": {
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The cookie only: an API token never mints its successor. Carries an `Idempotency-Key`.",
        "operationId": "rotate-token",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "description": "the new token, shown once; the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: an API token: this route takes the session cookie only (`cookie-only`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: the same key again with a different body",
            "x-problems": [
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "summary": "Rotate: the Sandbox's token version goes up (`ApiTokenRotated`) and every older token stops",
        "tags": [
          "token"
        ],
        "x-pr": 10,
        "x-session": "signed-in"
      }
    },
    "/v1/sandboxes/{id}/traffic": {
      "delete": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie.",
        "operationId": "stop-traffic",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrafficResponse"
                }
              }
            },
            "description": "the Simulator, stopped"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Stop simulated orders; the unused minutes go back to Control",
        "tags": [
          "traffic"
        ],
        "x-pr": 4,
        "x-session": "signed-in"
      },
      "get": {
        "description": "A session of sandbox `{id}`, a guest's included. The sandbox's API token may stand in for the cookie.",
        "operationId": "get-traffic",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrafficResponse"
                }
              }
            },
            "description": "`{running, rate, minutes_used, minutes_left, orders}`"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: with a token, the token's limit: every request it makes counts, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "The Simulator's state, today's",
        "tags": [
          "traffic"
        ],
        "x-pr": 4,
        "x-session": "sandbox"
      },
      "post": {
        "description": "A signed-in session of sandbox `{id}`; a guest gets 403 `guest-scope`. The sandbox's API token may stand in for the cookie. Carries an `Idempotency-Key`.",
        "operationId": "start-traffic",
        "parameters": [
          {
            "description": "The sandbox's ULID, from the session or the token.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TrafficRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrafficResponse"
                }
              }
            },
            "description": "the Simulator, running; the same `Idempotency-Key` again: the first answer, replayed",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`idempotency-key`: no `Idempotency-Key`, or not a ULID; `body`: a body that is not the contract's JSON; `token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "idempotency-key",
              "body",
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a token that is malformed, expired, rotated or not an API token (`token`, `expired`, `rotated`, `purpose`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`origin`: a cookie request without the storefront's exact `Origin`, or `Sec-Fetch-Site: cross-site`; `guest-scope`: a guest's session: sign in for this",
            "x-problems": [
              "origin",
              "guest-scope"
            ]
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "another sandbox's id, or one naming nothing"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`traffic-running`: a run is already going",
            "x-problems": [
              "traffic-running"
            ]
          },
          "410": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`wiped`: the sandbox is being wiped or is gone",
            "x-problems": [
              "wiped"
            ]
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`traffic`: naming the rule; `idempotency-key`: the same key again with a different body",
            "x-problems": [
              "traffic",
              "idempotency-key"
            ]
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`rate-limit`: the session's or IP hash's limit, or with a token the token's, with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "rate-limit"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`traffic-cap`: today's minutes are used; with `Retry-After`",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "x-problems": [
              "traffic-cap"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": []
          }
        ],
        "summary": "Start simulated orders, 1 to 6 a minute, within today's 30 minutes",
        "tags": [
          "traffic"
        ],
        "x-pr": 4,
        "x-session": "signed-in"
      }
    },
    "/v1/session": {
      "get": {
        "description": "Any session, a guest's included.",
        "operationId": "session",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            },
            "description": "the cookie, decoded"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: a cookie and a token both (`both`), or a token in the query string (`query`)",
            "x-problems": [
              "token"
            ]
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`token`: an API token: this route takes the session cookie only (`cookie-only`); `session`: no session, or one that does not verify",
            "x-problems": [
              "token",
              "session"
            ]
          }
        },
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "summary": "What the cookie says, read without an object call",
        "tags": [
          "sign-in"
        ],
        "x-pr": 3,
        "x-session": "any"
      }
    },
    "/v1/status": {
      "get": {
        "description": "Anyone.",
        "operationId": "status",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            },
            "description": "today's sandboxes, guests and demo accounts with their caps, the last snapshot of the kept Analytics Engine queries with `counters_as_of` and `counters_state` (`live`, `stale` or `unavailable`), the breaker's state (`unconfigured`, `armed`, `read-only` or `off`) with its last run, and the flag"
          }
        },
        "security": [],
        "summary": "Today's admission state, the status page's counters and the breaker's state, from the Control object",
        "tags": [
          "service"
        ],
        "x-pr": 2,
        "x-session": "public"
      }
    },
    "/v1/stripe/webhook": {
      "post": {
        "description": "Stripe only: its signature is the check.",
        "operationId": "stripe-webhook",
        "responses": {
          "200": {
            "description": "an event applied, replayed or ignored, and for a wiped or unknown sandbox"
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`signature`: the signature does not verify; `timestamp`: the signature's timestamp is outside the tolerance; `body`: not a Stripe event; `livemode`: a live-mode event",
            "x-problems": [
              "signature",
              "timestamp",
              "body",
              "livemode"
            ]
          },
          "405": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`OPTIONS`, with `Allow: POST`: no preflight"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`webhook-later`: an event `Billing` cannot apply yet",
            "x-problems": [
              "webhook-later"
            ]
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "`stripe-key`: the API has no sandbox Stripe key",
            "x-problems": [
              "stripe-key"
            ]
          }
        },
        "security": [
          {
            "stripeSignature": []
          }
        ],
        "summary": "Stripe's events, checked against `Stripe-Signature`, test mode only; no CORS, Origin, session, key or rate limit",
        "tags": [
          "payments"
        ],
        "x-pr": 5,
        "x-session": "stripe"
      }
    }
  },
  "servers": [
    {
      "description": "The API, from the launch (PR 11) on",
      "url": "https://api.bakery.ihaveasegway.com"
    },
    {
      "description": "The API on `wrangler dev`, as workers/api/README.md runs it",
      "url": "http://127.0.0.1:8788"
    }
  ],
  "tags": [
    {
      "name": "service"
    },
    {
      "name": "sign-in"
    },
    {
      "name": "sandbox"
    },
    {
      "name": "menu"
    },
    {
      "name": "orders"
    },
    {
      "name": "kitchen"
    },
    {
      "name": "traffic"
    },
    {
      "name": "payments"
    },
    {
      "name": "schedule"
    },
    {
      "name": "catering"
    },
    {
      "name": "crm"
    },
    {
      "name": "dispatch"
    },
    {
      "name": "token"
    }
  ]
}
