{"openapi":"3.1.0","info":{"title":"Aisle API","version":"v1","summary":"Run a wedding on Aisle behind your own frontend.","description":"Aisle's public backend API. Use it to run a wedding on Aisle while building\nand hosting your own frontend.\n\n## Authentication\n\nEvery request carries a wedding-scoped API key as a bearer token:\n\n    Authorization: Bearer <your key>\n\nA key is scoped to exactly one wedding, and every read and write it makes\nstays inside that wedding. **Keys are server-side credentials.** Call this\nAPI from your own backend and never ship a key in browser JavaScript, where\nanyone loading your site can read it and act as the couple.\n\n## Requests and responses\n\nBodies are JSON. A request that sends a body must send\n`Content-Type: application/json`.\n\nObject ids are opaque strings with a type prefix, such as `gst_1042`. Treat\nthem as strings: their shape may change and only the prefix is contractual.\n\n## Dates and times\n\nTwo kinds of value, and mixing them up is the most expensive mistake an\nintegration can make here, because the result is a plausible number rather\nthan an error.\n\n**Scheduled wedding times** are instants: RFC 3339 in UTC, for example\n`2026-06-13T14:00:00.000Z`. Event `starts_at` and `ends_at`,\nmeal-selection deadlines and transport-leg times are all instants.\n**Format them in the wedding's `timezone` from `GET /wedding`, never in\nthe reader's zone.** That ceremony is 16:00 at a wedding in `Europe/Rome`,\nand a guest browsing from California must still be told 16:00. Rendered in\nthe reader's own zone it reads 07:00, and a brunch the morning after moves to\nthe previous evening. Nothing in the response marks that as wrong, so it is\nworth getting right once in a shared formatter.\n\n**Record timestamps** are instants too, and the same RFC 3339 UTC shape:\n`created_at`, `updated_at` and `rsvp_responded_at` say when something\nhappened. Which zone you show those in is your choice, because they are not\npart of the wedding's schedule.\n\n**Wall-clock values** are a day or a time the couple owns at the venue, with\nno instant behind them, so they are carried as separate date and time fields:\n`wedding_date` and `wedding_end_date`, and stay `check_in_date` with\n`check_in_time`. These are the same for every reader and need no zone.\n\n`timezone` is null on a wedding with no venue yet. Instants written before\na venue was chosen were anchored to UTC.\n\n## Pagination\n\nCollections are cursor-paged. Pass `limit` (1 to 100, default\n25) and `cursor`. Each response carries `has_more` and\n`next_cursor`; keep passing `next_cursor` back until `has_more` is false.\nAn out-of-range `limit` is rejected rather than clamped, so a page you asked\nfor is either the page you get or an error.\n\n## Filtering\n\nFilters are query parameters named for the field they filter. Repeat a\nparameter, or comma-separate it, to mean \"any of these\":\n`?status=confirmed&status=pending`. Two different filters narrow each other.\nEach collection declares the filters it accepts; a parameter an endpoint does\nnot declare is rejected rather than ignored, so a misspelled filter is an\nerror and never a full page that looks filtered. A filter's `next_cursor` is\nbound to that filter, so keep passing the same query string while you page.\n\n## Errors\n\nFailures carry a JSON body with a stable `error.code`, a human-readable\n`error.message`, and a `request_id`. Branch on the code, log the message,\nand quote the request id when asking us about a specific call. Field-level\nproblems appear in `error.details`.\n\nA field we refuse is always a `422 validation_failed`, whether it arrived in\nthe query string or in the request body, and every field at fault is listed in\n`error.details` rather than only the first. Each entry names the field in the\nspelling you sent, dotted through objects and indexed through lists, such as\n`options.1.id`. `error.message` is one sentence for the whole request and\ncarries nothing you need to parse. A `400 invalid_request` means the request\nitself could not be read, such as a body that is not a JSON object.\n\n## Rate limits\n\nResponses carry `X-RateLimit-Limit`,\n`X-RateLimit-Remaining` and `X-RateLimit-Reset`. Over\nquota is a `429` with `Retry-After` in seconds.\n\n## Versioning\n\nThe version is in the path. Removing a field, renaming one, or narrowing what\na value can be is breaking and ships as a new version; adding a field or an\noptional parameter is not, and ships in place. **Ignore fields you do not\nrecognise** so a new one never breaks your integration.\n\nA retired endpoint keeps answering and starts sending RFC 8594\n`Deprecation` and `Sunset` headers, with at least\n180 days between them.\n\n# Build on Aisle\n\nThe Aisle API is a server-to-server backend for a frontend you own. Store the wedding-scoped key as `AISLE_API_KEY` on your server. Never put it in browser JavaScript or a `NEXT_PUBLIC_*` variable. Your browser calls a route you control; that route authenticates your user and calls Aisle.\n\n## First request\n\n```bash\ncurl 'https://api.aisle.wedding/v1/wedding' \\\n  --header \"Authorization: Bearer $AISLE_API_KEY\" \\\n  --header 'Accept: application/json'\n```\n\n```ts\nconst response = await fetch('https://api.aisle.wedding/v1/guests?limit=25', {\n  headers: { authorization: `Bearer ${process.env.AISLE_API_KEY}` },\n  cache: 'no-store',\n});\nif (!response.ok) throw new Error(`Aisle request failed: ${response.status}`);\nconst page = await response.json();\nconst next = page.has_more ? page.next_cursor : null;\n```\n\nCollections accept `limit` from 1 through 100, default 25. Pass the opaque `next_cursor` back unchanged. Errors use `{ \"error\": { \"code\", \"message\", \"details\" }, \"request_id\" }`.\n\n## Next.js server route\n\n```ts\n// app/api/wedding/route.ts\nexport async function GET(request: Request) {\n  const user = await requireYourApplicationUser(request);\n  if (!user) return Response.json({ error: 'Unauthorized' }, { status: 401 });\n  const response = await fetch('https://api.aisle.wedding/v1/wedding', {\n    headers: { authorization: `Bearer ${process.env.AISLE_API_KEY}` },\n    cache: 'no-store',\n  });\n  return new Response(response.body, {\n    status: response.status,\n    headers: { 'content-type': 'application/json' },\n  });\n}\n```\n\n## Rendering a page\n\nA wedding page needs a dozen collections, and one request each is 27 requests\nagainst a limit of 120 a minute. Ask `GET /site` for them instead. `expand`\ntakes up to five collection names, comma-separated or repeated, and returns\neach one inline under `collections`:\n\n```ts\nconst site = await aisle('/site?expand=events,dress_codes,faqs,recommendations,photos');\nconst events = site.data.collections.events.data;\n```\n\nEvery entry is a page in the same shape a collection endpoint returns, with\nits own `has_more` and `next_cursor`, and the rows are the rows that\nendpoint returns. It is a warm start rather than a way around pagination: you\nget the first 25 of each, and you page on at the collection's own endpoint\nwith the cursor beside it. Filters stay there too, so fetch a single photo\nsection from `GET /photos?section=` rather than expanding all of them.\n\nCache what you render. These reads are uncached, so a server rendering on\ndemand without a cache of its own runs out of quota at four page views a\nminute.\n\n## Guest-site typography and dress labels\n\nThe design resource accepts `paragraph_font`: `heading` preserves the existing\nparagraph style and `body` uses the selected `font_body` for prose. Read the\nresolved choice from `GET /site/design`, or change it with `PATCH /site/design`.\nHeadings keep `font_heading`. Omitting the setting preserves existing behavior;\nwriting null resets it to `heading`.\n\nFor shared dress guidance, send `{ \"set\": { \"show_gender_labels\": false } }`\nto `PATCH /site/chapters/dress`. Both descriptions and their mood boards remain\nvisible; one populated description displays as one blurb. Omitted or true keeps\nthe For her / For him headings. Chapter content returned by `GET /site` uses\nthe same `show_gender_labels` spelling. A custom frontend should honor these\nchoices when rendering the site.\n\n## The design spec\n\nWhere the design spec is on for a wedding, `GET /site/design` (and `design`\non `GET /site`) adds `spec`: every token, each section's arrangement, its\nsettings and the styles on the reply's and room picker's parts, and the blocks\nthe site holds with where each draws (never their markup). It is read-only and\nabsent everywhere else, so read the fields beside it as before. `spec` holds\nwhat the couple chose; the fields beside it report the contrast floors. When\n`legacy_document` is true, guests are served a whole-page design that reads\nnone of it.\n\n## Cover RSVP button\n\nSend `{ \"set\": { \"show_rsvp_button\": true } }` to\n`PATCH /site/chapters/masthead` to add an RSVP button to a standard Aisle cover.\n`GET /site` returns the saved choice as `content.show_rsvp_button`. Omit it to\npreserve the choice; `false` or `null` turns it off. The default is off.\nThe button only appears when the current viewer can access the enabled RSVP\nchapter. Read-only shared links never show it. Brief keeps its existing RSVP\nlink without a duplicate, and custom HTML covers keep their own controls.\n\n## Travel photo position\n\nSend `{ \"set\": { \"photo_position\": \"below-description\" } }` to\n`PATCH /site/chapters/travel` to put the optional photo after the standfirst\nand body paragraphs, before the airports. `above-description` is the existing\ndefault. Omit to preserve the setting; set `null` to restore the default.\n`GET /site` returns it as `content.photo_position`. No photo adds no image\nor spacing; other chapters retain their placement.\n\n## Links in chapter prose\n\nChapter prose may contain `[label](https://example.com/)` links. This applies\nto `standfirst`, masthead `subhead`, letter/stay/travel/custom `body`\nparagraphs, closing `note` and guestbook `prompt`, including translations.\nThe API preserves the notation in existing string fields. Plain text keeps\nworking; no new field or request shape is required.\n\nInterpret only HTTP(S) links without credentials, spaces or control characters.\nLabels are single-line text; backslashes escape backslashes and square brackets\ninside labels. Encode parentheses in destinations as `%28` and `%29`.\nOther Markdown and HTML stay literal text. Render text and validated links\nseparately, never pass these strings to raw HTML rendering. A frontend that\ndoes not render links can display their labels as plain text.\n\n## Times\n\nEvent times are instants. Format them in the wedding's own `timezone`, never\nin the reader's, or a guest outside the venue's zone is shown the wrong hour\nwith nothing to say it is wrong.\n\n```ts\nconst { timezone } = await getWedding(); // 'Europe/Rome', null before a venue\nconst at = new Intl.DateTimeFormat('en-GB', {\n  timeZone: timezone ?? 'UTC',\n  dateStyle: 'medium',\n  timeStyle: 'short',\n}).format(new Date(event.starts_at)); // 13 Jun 2026, 16:00\n```\n\nA wedding with no `timezone` yet stores its times as though the zone were UTC.\nSetting the real one through `PATCH /wedding` rewrites those times so the clock\nthe couple entered survives, so read the events again after such a write.\nChanging a zone that is already set leaves the stored instants where they are.\n\nAn event with `all_day: true` is a day, such as a travel day, not a time. Its\n`starts_at` is the start of that day in the wedding's zone and `ends_at`, when\nset, the start of its last day: format them with `dateStyle` alone, in the\nsame zone, and show no clock.\n\n`wedding_date` is the opposite: a calendar day, the same for every reader,\nwith no instant behind it. Do not put it through `new Date()` and format it in\na zone, which moves it a day west of UTC.\n\n## Retries\n\nRetry a 429 only after `Retry-After`. GET requests can be retried with bounded exponential backoff. General idempotency-key persistence is not part of this beta. After a lost write response, read the resource and reconcile before a deliberate retry. For a lost plus-one response, list guests and find a row whose `plus_one_for_guest_id` is the inviter. Each operation documents any stronger rule it supports.\n\n## Guest identity\n\nCreate an individual or group invitation credential through `POST /guest-access`. Exchange its one-time-display code through `POST /guest-access/verify` from your backend, then keep the returned session token in your own server-managed session or an HttpOnly cookie. Before every personalised site read or RSVP write, call `POST /guest-access/sessions/verify`. Include the selected `guest_id` for group access, then call the personalised guest endpoint only after verification succeeds. This keeps the Aisle key server-only and prevents a browser-supplied guest id from widening access. Rotation, revocation, expiry and membership changes take effect on the next verification.\n\n## Named parties\n\nUse `GET /parties` to read existing households and `POST /parties` with `{name, guest_ids}` to create one. Creation is atomic, accepts up to 200 distinct guests, and allows empty or single-member parties. The first supplied guest leads; later members inherit that reply against their own invitations. `PATCH /parties/{party_id}` changes the name, with null clearing it. `PUT /parties/{party_id}/guests/{guest_id}` joins a guest and DELETE unlinks them. Both repair leadership and preserve the accommodation-payment guard. `GET /guests?party_id=pty_...` reads member records through the standard cursor page. Existing party IDs and `party_with_guest_id` remain supported; empty parties retain their identity and are not deleted.\n\nA party ID is not a login code. Parties decide who replies together; guest access credentials decide who may sign in together. Keep these memberships separate so each selected guest retains their own invitations and answers. Return personalised guest projections to browsers rather than management guest records. After a lost party-create response, list and reconcile before retrying.\n\n## Uploads and payments\n\nThe uploads operation returns provider instructions to a server-authenticated request. The browser can send a file through your same-origin proxy, but your proxy alone adds the Aisle bearer key. Use the public wedding id returned by `GET /wedding` in the documented pathname and register the returned owned URL.\n\nPayment operations require the `payments` scope, which is a box to tick when the key is created in Settings. A key made without it answers `403`, and scopes are fixed once a key exists, so make a new one. Aisle computes prices, fees, instalments, eligibility, and settlement state. A lost checkout response must be reconciled against the payment list before another checkout.\n\n## Taking a registry gift\n\nA gift is three steps: your server asks Aisle for a checkout, your browser confirms it with Stripe, and your server reads the payment back.\n\n```ts\n// app/api/gift/route.ts, on your server\nexport async function POST(request: Request) {\n  const { registry_item_id, amount, name, email, message } = await request.json();\n  const response = await fetch('https://api.aisle.wedding/v1/checkouts', {\n    method: 'POST',\n    headers: {\n      authorization: `Bearer ${process.env.AISLE_API_KEY}`,\n      'content-type': 'application/json',\n    },\n    body: JSON.stringify({\n      type: 'registry_contribution',\n      registry_item_id, // reg_... from GET /registry/items\n      amount, // the giver's choice, above 0 and at most 10000\n      contributor_name: name,\n      contributor_email: email,\n      message,\n    }),\n  });\n  const { data, error } = await response.json();\n  if (!response.ok) return Response.json({ error: error.message }, { status: response.status });\n  // These three are safe in the browser. The Aisle key is not.\n  return Response.json({\n    payment_id: data.payment_id,\n    client_secret: data.client_secret,\n    stripe_publishable_key: data.stripe_publishable_key,\n    amount: data.amount,\n  });\n}\n```\n\n```tsx\n// the browser\nimport { Elements, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js';\nimport { loadStripe } from '@stripe/stripe-js';\n\nfunction Gift({ gift }: { gift: { client_secret: string; stripe_publishable_key: string } }) {\n  // Aisle's key, and no stripeAccount option.\n  const [stripe] = useState(() => loadStripe(gift.stripe_publishable_key));\n  return (\n    <Elements stripe={stripe} options={{ clientSecret: gift.client_secret }}>\n      <GiftForm />\n    </Elements>\n  );\n}\n\nfunction GiftForm() {\n  const stripe = useStripe();\n  const elements = useElements();\n  async function pay() {\n    if (!stripe || !elements) return;\n    const { error } = await stripe.confirmPayment({ elements, redirect: 'if_required' });\n    if (error) showTheGiver(error.message);\n  }\n  return (\n    <form action={pay}>\n      <PaymentElement />\n      <button type=\"submit\">Give</button>\n    </form>\n  );\n}\n```\n\n`stripe_publishable_key` is Aisle's key, not one of yours. The charge is created on Aisle's Stripe account and paid out to the couple's connected bank, so a publishable key from your own Stripe account cannot confirm it, and you need no Stripe account at all. Take it from each checkout response rather than hard-coding it.\n\nWho is giving decides the body. An invited guest you have already identified gives with `guest_id`. Anyone else gives with `contributor_name` and `contributor_email`, which is where Stripe sends the receipt; send one or the other, never both. A gift without a `guest_id` needs the wedding's public registry switched on: read `public_registry_enabled` from `GET /wedding` and set it with `PATCH /wedding`, or on the Budget page. With it off the checkout answers `403`.\n\nShow `amount` from the response as what the card is charged: it includes the service fee when the couple passes it on (`guest_pays_platform_fee` on the wedding). After `confirmPayment` resolves without an error, poll `GET /payments/{payment_id}` from your server until `status` is `completed`; Aisle settles it when Stripe's webhook arrives. Registry totals in `GET /registry/summary` count the gift from then on. Payouts must be connected first; `GET /payouts/status` says whether they are.\n\n## Hotel photos\n\nProperty reads include `images`, an ordered list of up to six HTTPS photo URLs.\nSend `images` when creating a property or patching `/properties/{property_id}`.\nAn omitted field preserves the photos already saved; `{ \"images\": [] }` clears\nthem. Properties without photos return an empty list. Room photos stay on each\nroom's own `images` field.\n\n## Room choice by property\n\nProperty resources also return `room_selection_mode` (`couple_assigned`, `guest_choice`, or null) and `effective_room_selection_mode`. The first is the stored property override; null inherits the wedding setting, with `couple_assigned` as the final fallback. Property create and PATCH accept the optional nullable override. A non-null value requires the resulting arrangement to be `hosted_rooms`; null clears it, and omission on PATCH preserves it. Prefer this field for individual Hosted places. The existing wedding `room_selection_mode` remains a legacy bulk setter: explicitly writing it changes the fallback and clears every property override, even when the wedding value is unchanged.\n\n## Room-assignment emails\n\nRoom-assignment emails are off by default. If the couple enables them in Stays,\ncreating a guest with a room or changing an existing guest's room through the\nAPI can queue an email. It links to the wedding site without quoting a balance\nor charging the guest. It requires a published site with Stay available and the\nguest's own email; known under-13 guests, declined guests and opted-out addresses\nare excluded. Delivery is asynchronous and is rechecked against current access,\ncontact and assignment. Clearing a room or repeating its current assignment\nsends no new notice. Enabling the preference does not notify prior assignments.\n\n## Removing rooms\n\n`DELETE /rooms/{room_id}` removes a room from active inventory and clears its guest assignments. Cancellation is attempted only after Stripe reports no payment method and no charge; removing a room with a checkout requires confirmed cancellation. Checkout and payment history is retained. Completed or refunded payments, processing payments, and active checkouts with a card entered still return `409`; show the returned error message so the couple can understand the refusal. A removed room is absent from room collections and returns `404` on subsequent room reads.\n\nIf the room shares a household charge with another room, a payment record or an active or Stripe-linked checkout attempt on that other room also returns `409`. Deleting one room never cancels another room's checkout.\n\n## Compatibility\n\nAdding optional fields and endpoints is compatible. Removing or narrowing a documented value requires a new API version. A deprecated v1 operation receives at least 180 days of notice. Ignore response fields you do not recognise.","contact":{"name":"Aisle","url":"https://aisle.wedding"}},"servers":[{"url":"https://api.aisle.wedding/v1","description":"Production"}],"externalDocs":{"url":"https://api.aisle.wedding/docs","description":"API reference"},"security":[{"bearerAuth":[]}],"tags":[{"name":"Meta","description":"Service discovery and connectivity checks."},{"name":"Wedding","description":"Wedding identity and dates."},{"name":"Site","description":"Guest-site content and publication."},{"name":"Events","description":"Wedding schedule and invitations."},{"name":"Dress codes","description":"Reusable event dress guidance."},{"name":"Guests","description":"Manage the wedding guest list and room assignments."},{"name":"RSVP","description":"Read and record guest replies and event invitations."},{"name":"Parties","description":"Named households whose members reply together. Codes and guest sessions are managed by your application."},{"name":"Guest access","description":"Individual and group invitation codes for custom frontends. Access grants name explicit guests and never change RSVP Parties. All operations require a server-side wedding API key; a guest session token is not an API key."},{"name":"Stays","description":"Properties, rooms, rates, payment schedules, and stay dates."},{"name":"Travel","description":"Airports and their transport options."},{"name":"Recommendations","description":"Recommendations and frequently asked questions."},{"name":"Registry","description":"Registry items and settled contribution ledger views."},{"name":"Media","description":"Wedding-owned uploads, gallery photos, and the site cover."},{"name":"Guest content","description":"Guestbook notes, song requests, and predictions."},{"name":"Statistics","description":"Canonical wedding counts and settled money totals."},{"name":"Payments","description":"Create guest checkouts and read the wedding-scoped payment ledger."},{"name":"Payouts","description":"Connect and inspect the couple payout account."}],"paths":{"/meta":{"get":{"tags":["Meta"],"operationId":"getMeta","summary":"Describe this API","description":"Returns the version this deployment serves and where to find its documentation. Requires no credentials, so it is the call to make when checking that your client reaches Aisle at all.","security":[],"responses":{"200":{"description":"Service description.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Meta"}}}},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/wedding":{"get":{"operationId":"getWedding","tags":["Wedding"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Wedding"}},"required":["data"]},"example":{"data":{"id":"wed_01J8WEDDING","slug":"maya-and-theo","partner_1_name":"Maya","partner_2_name":"Theo","couple_display_name":"Maya & Theo","wedding_date":"2027-06-13","wedding_end_date":"2027-06-15","timezone":"Europe/Rome","currency":"EUR","location":"Ravello, Italy","venue":{"name":"Villa Cimbrone","place_id":null,"latitude":"40.6499","longitude":"14.6117","city":"Ravello","country":"Italy"},"room_selection_mode":"guest_choice","guest_pays_platform_fee":false,"room_payment_on_rsvp":false,"public_registry_enabled":true,"published":true,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"updateWedding","tags":["Wedding"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"partner_1_name":{"type":"string"},"partner_2_name":{"type":"string"},"couple_display_name":{"type":["string","null"]},"wedding_date":{"type":["string","null"],"format":"date","description":"A calendar day the couple owns in the venue's zone, with no instant behind it. It is the same day for every reader."},"wedding_end_date":{"type":["string","null"],"format":"date","description":"A calendar day the couple owns in the venue's zone, with no instant behind it. It is the same day for every reader."},"location":{"type":["string","null"]},"venue_name":{"type":["string","null"]},"place_id":{"type":["string","null"]},"latitude":{"description":"A decimal from -90 through 90.","oneOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"longitude":{"description":"A decimal from -180 through 180.","oneOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:[0-9]?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"city":{"type":["string","null"]},"country":{"type":["string","null"]},"timezone":{"type":["string","null"],"description":"The IANA zone of the venue, such as `Europe/Rome`. Every instant this API returns is meant to be read in this zone. Null on a wedding with no venue yet, in which case instants were written against UTC."},"room_selection_mode":{"description":"Legacy bulk setter: updates the wedding fallback and clears every property override, including when the value is unchanged. Prefer property room_selection_mode for individual Hosted places.","type":"string","enum":["couple_assigned","guest_choice"]},"public_registry_enabled":{"type":"boolean"}}},"example":{"wedding_date":"2027-06-13","venue_name":"Villa Cimbrone"}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Wedding"}},"required":["data"]},"example":{"data":{"id":"wed_01J8WEDDING","slug":"maya-and-theo","partner_1_name":"Maya","partner_2_name":"Theo","couple_display_name":"Maya & Theo","wedding_date":"2027-06-13","wedding_end_date":"2027-06-15","timezone":"Europe/Rome","currency":"EUR","location":"Ravello, Italy","venue":{"name":"Villa Cimbrone","place_id":null,"latitude":"40.6499","longitude":"14.6117","city":"Ravello","country":"Italy"},"room_selection_mode":"guest_choice","guest_pays_platform_fee":false,"room_payment_on_rsvp":false,"public_registry_enabled":true,"published":true,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site":{"get":{"operationId":"getSite","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Returns the site shell, and optionally the first page of the collections that fill it. Without `expand` this is the shell alone and each collection is its own request, which is 27 of them for a complete page. `expand` is a warm start, not a way around pagination: each collection comes back as the page its own endpoint would return first, and you continue on that endpoint with its `next_cursor`.","parameters":[{"name":"expand","in":"query","required":false,"description":"Collections to return inline under `collections`, at most 5 per request. Repeat the parameter, or comma-separate its values.","style":"form","explode":true,"schema":{"type":"array","maxItems":5,"items":{"type":"string","enum":["events","dress_codes","properties","rooms","airports","recommendations","faqs","registry_items","songs","predictions","guestbook","photos"]}}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteWithCollections"}},"required":["data"]},"example":{"data":{"slug":"maya-and-theo","published":true,"hero_image_url":null,"design":{"primary":"#1F3B2D","accent":"#B5552F","font_heading":"Newsreader","font_body":"Manrope","ground":"#F5EFE4","ink":"#1A1816","muted":"#6B655E","rule":"#D8D0C4","radius":4,"cover":"full","nav_mode":"scroll","paragraph_font":"heading","spacing_scale":1,"text_scale":1,"hero_text_color":null,"adjusted":{"ink":false,"muted":false,"primary":false}},"chapters":[{"key":"masthead","kind":"fixed","position":0,"enabled":true,"content":{"show_countdown":true}}],"collections":{"events":{"data":[{"id":"evt_01J8EVENT","name":"Welcome dinner","type":"welcome_dinner","starts_at":"2027-06-13T18:00:00.000Z","ends_at":null,"all_day":false,"venue":{"name":"The terrace","address":null,"latitude":null,"longitude":null},"description":null,"images":[],"dress_code_id":null,"meal_selection":{"enabled":false,"deadline":null,"options":[]},"ticket":{"required":false,"price":null,"pay_later":false},"rsvp":{"asks_separately":true,"options":null},"visibility":"public","audience_tags":[],"audience_property_ids":[],"transport_note":null,"transport_legs":[],"sort_order":0,"seating_not_required":false,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}],"has_more":false,"next_cursor":null},"dress_codes":{"data":[{"id":"drc_01J8DRESS","name":"Garden formal","description_ladies":null,"pinterest_url_ladies":null,"description_men":null,"pinterest_url_men":null,"inspiration_images":[],"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}],"has_more":false,"next_cursor":null}}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/published":{"get":{"operationId":"getPublishedSite","tags":["Site"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublishedSite"}},"required":["data"]},"example":{"data":{"wedding":{"id":"wed_01J8WEDDING","slug":"maya-and-theo","partner_1_name":"Maya","partner_2_name":"Theo","couple_display_name":"Maya & Theo","wedding_date":"2027-06-13","wedding_end_date":"2027-06-15","timezone":"Europe/Rome","currency":"EUR","location":"Ravello, Italy","venue":{"name":"Villa Cimbrone","place_id":null,"latitude":"40.6499","longitude":"14.6117","city":"Ravello","country":"Italy"},"room_selection_mode":"guest_choice","guest_pays_platform_fee":false,"room_payment_on_rsvp":false,"public_registry_enabled":true,"published":true,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"},"site":{"slug":"maya-and-theo","published":true,"hero_image_url":null,"design":{"primary":"#1F3B2D","accent":"#B5552F","font_heading":"Newsreader","font_body":"Manrope","ground":"#F5EFE4","ink":"#1A1816","muted":"#6B655E","rule":"#D8D0C4","radius":4,"cover":"full","nav_mode":"scroll","paragraph_font":"heading","spacing_scale":1,"text_scale":1,"hero_text_color":null,"adjusted":{"ink":false,"muted":false,"primary":false}},"chapters":[{"key":"masthead","kind":"fixed","position":0,"enabled":true,"content":{"show_countdown":true}}]},"events":[{"id":"evt_01J8EVENT","name":"Welcome dinner","type":"welcome_dinner","starts_at":"2027-06-13T18:00:00.000Z","ends_at":null,"all_day":false,"venue":{"name":"The terrace","address":null,"latitude":null,"longitude":null},"description":null,"images":[],"dress_code_id":null,"meal_selection":{"enabled":false,"deadline":null,"options":[]},"ticket":{"required":false,"price":null,"pay_later":false},"rsvp":{"asks_separately":true,"options":null},"visibility":"public","audience_tags":[],"audience_property_ids":[],"transport_note":null,"transport_legs":[],"sort_order":0,"seating_not_required":false,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/publication":{"put":{"operationId":"setSitePublication","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Publication"},"example":{"published":true}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Publication"}},"required":["data"]},"example":{"data":{"published":true}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/design":{"get":{"operationId":"getSiteDesign","tags":["Site"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteDesign"}},"required":["data"]},"example":{"data":{"primary":"#1F3B2D","accent":"#B5552F","font_heading":"Newsreader","font_body":"Manrope","ground":"#F5EFE4","ink":"#1A1816","muted":"#6B655E","rule":"#D8D0C4","radius":4,"cover":"full","nav_mode":"scroll","paragraph_font":"heading","spacing_scale":1,"text_scale":1,"hero_text_color":null,"adjusted":{"ink":false,"muted":false,"primary":false}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"updateSiteDesign","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"primary":{"type":"string"},"accent":{"type":"string"},"font_heading":{"type":"string"},"font_body":{"type":"string"},"ground":{"type":["string","null"]},"ink":{"type":["string","null"]},"muted":{"type":["string","null"]},"rule":{"type":["string","null"]},"radius":{"type":["number","null"]},"cover":{"type":["string","null"],"enum":["full","framed","type","split",null]},"nav_mode":{"type":["string","null"],"enum":["scroll","tabs",null]},"paragraph_font":{"type":["string","null"],"enum":["heading","body",null],"description":"Authored paragraphs use the heading font by default. Choose body to use the selected body font while keeping headings unchanged. Null restores the default."},"spacing_scale":{"type":"number"},"text_scale":{"type":"number"},"hero_text_color":{"type":["string","null"]}}},"example":{"primary":"#1F3B2D","nav_mode":"scroll"}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteDesign"}},"required":["data"]},"example":{"data":{"primary":"#1F3B2D","accent":"#B5552F","font_heading":"Newsreader","font_body":"Manrope","ground":"#F5EFE4","ink":"#1A1816","muted":"#6B655E","rule":"#D8D0C4","radius":4,"cover":"full","nav_mode":"scroll","paragraph_font":"heading","spacing_scale":1,"text_scale":1,"hero_text_color":null,"adjusted":{"ink":false,"muted":false,"primary":false}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/chapters":{"get":{"operationId":"listSiteChapters","tags":["Site"],"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A cursor-paged collection.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SiteChapter"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"example":{"data":[{"key":"masthead","kind":"fixed","position":0,"enabled":true,"content":{"show_countdown":true}}],"has_more":false,"next_cursor":null}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/chapters/{chapter_key}":{"patch":{"operationId":"updateSiteChapter","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Retrying enabled or set with the same values is safe. Retrying ops is not safe because list operations may apply twice; read the chapter before retrying after a lost response.","parameters":[{"name":"chapter_key","in":"path","required":true,"description":"A fixed or custom chapter key.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"set":{"type":"object","additionalProperties":true,"description":"Chapter settings to merge. For shared dress guidance, PATCH the dress chapter with show_gender_labels: false. Set true to restore labels. Chapter prose strings support selected-text links as [label](https://example.com/). This applies to standfirst, masthead.subhead, letter/stay/travel/custom body paragraphs, closing.note and guestbook.prompt, including their translations. Only HTTP(S) destinations without credentials, spaces or control characters are links; other markup stays literal text. Strings retain this notation in API reads and writes. Render text and validated links separately, never as raw HTML. For the travel chapter, photo_position is above-description (default) or below-description. Below places the optional photo after the standfirst and body paragraphs, before the airport list. Omit to keep the saved position; set null to restore the default. No photo means no image or extra spacing. For the masthead chapter, show_rsvp_button is an optional boolean, off when absent. True adds a cover link to RSVP on standard Aisle covers when the current viewer can access RSVP. Omit to preserve the setting; false or null turns it off. Read-only shared links and disabled RSVP never show it. Brief retains its existing RSVP link without adding a second button; custom HTML covers are unchanged."},"ops":{"type":"array","items":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"op":{"const":"question_upsert"},"question":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"prompt":{"type":"string"},"type":{"type":"string","enum":["text","yesno","choice","file","section"],"description":"section is a heading over the questions after it and takes no answer. file asks the guest for a photo or PDF on the wedding site; it cannot be answered through this API."},"required":{"type":"boolean","description":"A guest replying as attending on the wedding site must answer it. Not enforced on PUT /v1/guests/{guest_id}/rsvp."},"options":{"type":"array","items":{"type":"string"}},"event_id":{"type":"string","pattern":"^evt_.+$"},"audience_tags":{"type":"array","items":{"type":"string"}},"show_if":{"type":["object","null"],"additionalProperties":false,"properties":{"event_id":{"type":"string","pattern":"^evt_.+$"},"counts_as_in":{"type":"array","items":{"type":"string","enum":["attending","maybe","declined"]}}},"required":["event_id","counts_as_in"]}},"required":["id","prompt"]}},"required":["op","question"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"question_remove"},"question_id":{"type":"string"}},"required":["op","question_id"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"question_move"},"question_id":{"type":"string"},"to_index":{"type":"integer"}},"required":["op","question_id","to_index"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"photo_add"},"url":{"type":"string"}},"required":["op","url"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"photo_remove"},"url":{"type":"string"}},"required":["op","url"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"paragraph_set"},"index":{"type":"integer"},"text":{"type":"string"}},"required":["op","index","text"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"paragraph_insert"},"index":{"type":"integer"},"text":{"type":"string"}},"required":["op","index","text"]},{"type":"object","additionalProperties":false,"properties":{"op":{"const":"paragraph_remove"},"index":{"type":"integer"}},"required":["op","index"]}]}}}},"example":{"enabled":true,"set":{"show_countdown":true}}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteChapter"}},"required":["data"]},"example":{"data":{"key":"masthead","kind":"fixed","position":0,"enabled":true,"content":{"show_countdown":true}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/chapter-order":{"put":{"operationId":"reorderSiteChapters","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChapterOrder"},"example":{"order":["masthead","weekend","rsvp"]}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ChapterOrder"}},"required":["data"]},"example":{"data":{"order":["masthead","weekend","rsvp"]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/languages":{"get":{"operationId":"getSiteLanguages","tags":["Site"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteLanguages"}},"required":["data"]},"example":{"data":{"default":"en","additional":["es"]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"operationId":"updateSiteLanguages","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteLanguagesPatch"},"example":{"default":"en","additional":["es"]}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteLanguages"}},"required":["data"]},"example":{"data":{"default":"en","additional":["es"]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/translations/{language}":{"get":{"operationId":"getSiteTranslations","tags":["Site"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"language","in":"path","required":true,"description":"A supported guest-site language code.","schema":{"type":"string","enum":["en","es","fr","it","de","pt","pl"]}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteTranslations"}},"required":["data"]},"example":{"data":{"masthead":{"eyebrow":"Bienvenidos"}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"operationId":"updateSiteTranslations","tags":["Site"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","parameters":[{"name":"language","in":"path","required":true,"description":"A supported guest-site language code.","schema":{"type":"string","enum":["en","es","fr","it","de","pt","pl"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"sections":{"type":"object","additionalProperties":{"type":"object"}}},"required":["sections"]},"example":{"sections":{"masthead":{"eyebrow":"Bienvenidos"}}}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SiteTranslations"}},"required":["data"]},"example":{"data":{"masthead":{"eyebrow":"Bienvenidos"}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/events":{"get":{"operationId":"listEvents","tags":["Events"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"type","in":"query","required":false,"description":"Return only events of this type. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["welcome_dinner","ceremony","reception","brunch","rehearsal","cocktail_hour","after_party","activity","other"]}}},{"name":"visibility","in":"query","required":false,"description":"Return only events with this visibility. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["public","invite_only","internal"]}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A cursor-paged collection.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"example":{"data":[{"id":"evt_01J8EVENT","name":"Welcome dinner","type":"welcome_dinner","starts_at":"2027-06-13T18:00:00.000Z","ends_at":null,"all_day":false,"venue":{"name":"The terrace","address":null,"latitude":null,"longitude":null},"description":null,"images":[],"dress_code_id":null,"meal_selection":{"enabled":false,"deadline":null,"options":[]},"ticket":{"required":false,"price":null,"pay_later":false},"rsvp":{"asks_separately":true,"options":null},"visibility":"public","audience_tags":[],"audience_property_ids":[],"transport_note":null,"transport_legs":[],"sort_order":0,"seating_not_required":false,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}],"has_more":false,"next_cursor":null}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"createEvent","tags":["Events"],"security":[{"bearerAuth":[]}],"description":"Retry is not safe after a lost response. List the collection before creating again.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"type":{"type":"string","enum":["welcome_dinner","ceremony","reception","brunch","rehearsal","cocktail_hour","after_party","activity","other"]},"starts_at":{"type":"string","format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"ends_at":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"all_day":{"type":"boolean","description":"True for an all-day item, such as a travel day: it has a day and no time. `starts_at` is then the start of its first day in the wedding's `timezone` and `ends_at`, when set, the start of its last day; show the days, never midnight. On a write, any time sent with the days is dropped. Defaults to false."},"venue_name":{"type":["string","null"]},"venue_address":{"type":["string","null"]},"venue_latitude":{"description":"A decimal from -90 through 90.","oneOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"venue_longitude":{"description":"A decimal from -180 through 180.","oneOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:[0-9]?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"description":{"type":["string","null"]},"images":{"type":"array","items":{"type":"string"}},"dress_code_id":{"type":["string","null"],"pattern":"^drc_.+$"},"has_meal_selection":{"type":"boolean"},"meal_options":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"dietary_tags":{"type":"array","items":{"type":"string"}}},"required":["id","name"]}},"meal_selection_deadline":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"requires_ticket":{"type":"boolean"},"ticket_price":{"description":"A decimal from 0 through 99999999.99.","oneOf":[{"type":"number","minimum":0,"maximum":99999999.99,"multipleOf":0.01},{"type":"string","pattern":"^(?:0|[1-9]\\d{0,7})(?:\\.\\d{1,2})?$"},{"type":"null"}]},"ticket_pay_later":{"type":"boolean","description":"Let guests reply yes before paying for the ticket. Read back as `ticket.pay_later`."},"asks_rsvp":{"type":"boolean"},"rsvp_options":{"type":["array","null"],"items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"counts_as":{"type":"string","enum":["attending","maybe","declined"]}},"required":["id","label","counts_as"]}},"visibility":{"type":"string","enum":["public","invite_only","internal"]},"transport_note":{"type":["string","null"]},"audience_tags":{"type":"array","items":{"type":"string"}},"audience_property_ids":{"type":"array","items":{"type":"string","pattern":"^prp_.+$"}},"transport_legs":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"location":{"type":"string"},"time":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"note":{"type":["string","null"]},"audience_tags":{"type":"array","items":{"type":"string"}},"audience_properties":{"type":"array","items":{"type":"string","pattern":"^prp_.+$"}},"audience_undecided":{"type":"boolean"}},"required":["id","location","time","note","audience_tags","audience_properties"]}},"sort_order":{"type":"integer"},"seating_not_required":{"type":"boolean"}},"required":["name","starts_at"]},"example":{"name":"Welcome dinner","starts_at":"2027-06-13T18:00:00.000Z","asks_rsvp":true}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Event"}},"required":["data"]},"example":{"data":{"id":"evt_01J8EVENT","name":"Welcome dinner","type":"welcome_dinner","starts_at":"2027-06-13T18:00:00.000Z","ends_at":null,"all_day":false,"venue":{"name":"The terrace","address":null,"latitude":null,"longitude":null},"description":null,"images":[],"dress_code_id":null,"meal_selection":{"enabled":false,"deadline":null,"options":[]},"ticket":{"required":false,"price":null,"pay_later":false},"rsvp":{"asks_separately":true,"options":null},"visibility":"public","audience_tags":[],"audience_property_ids":[],"transport_note":null,"transport_legs":[],"sort_order":0,"seating_not_required":false,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/events/{event_id}":{"get":{"operationId":"getEvent","tags":["Events"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"event_id","in":"path","required":true,"description":"An evt_-prefixed event id.","schema":{"type":"string","pattern":"^evt_.+$"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Event"}},"required":["data"]},"example":{"data":{"id":"evt_01J8EVENT","name":"Welcome dinner","type":"welcome_dinner","starts_at":"2027-06-13T18:00:00.000Z","ends_at":null,"all_day":false,"venue":{"name":"The terrace","address":null,"latitude":null,"longitude":null},"description":null,"images":[],"dress_code_id":null,"meal_selection":{"enabled":false,"deadline":null,"options":[]},"ticket":{"required":false,"price":null,"pay_later":false},"rsvp":{"asks_separately":true,"options":null},"visibility":"public","audience_tags":[],"audience_property_ids":[],"transport_note":null,"transport_legs":[],"sort_order":0,"seating_not_required":false,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"updateEvent","tags":["Events"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","parameters":[{"name":"event_id","in":"path","required":true,"description":"An evt_-prefixed event id.","schema":{"type":"string","pattern":"^evt_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"type":{"type":"string","enum":["welcome_dinner","ceremony","reception","brunch","rehearsal","cocktail_hour","after_party","activity","other"]},"starts_at":{"type":"string","format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"ends_at":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"all_day":{"type":"boolean","description":"True for an all-day item, such as a travel day: it has a day and no time. `starts_at` is then the start of its first day in the wedding's `timezone` and `ends_at`, when set, the start of its last day; show the days, never midnight. On a write, any time sent with the days is dropped. Defaults to false."},"venue_name":{"type":["string","null"]},"venue_address":{"type":["string","null"]},"venue_latitude":{"description":"A decimal from -90 through 90.","oneOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"venue_longitude":{"description":"A decimal from -180 through 180.","oneOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:[0-9]?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"description":{"type":["string","null"]},"images":{"type":"array","items":{"type":"string"}},"dress_code_id":{"type":["string","null"],"pattern":"^drc_.+$"},"has_meal_selection":{"type":"boolean"},"meal_options":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"dietary_tags":{"type":"array","items":{"type":"string"}}},"required":["id","name"]}},"meal_selection_deadline":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"requires_ticket":{"type":"boolean"},"ticket_price":{"description":"A decimal from 0 through 99999999.99.","oneOf":[{"type":"number","minimum":0,"maximum":99999999.99,"multipleOf":0.01},{"type":"string","pattern":"^(?:0|[1-9]\\d{0,7})(?:\\.\\d{1,2})?$"},{"type":"null"}]},"ticket_pay_later":{"type":"boolean","description":"Let guests reply yes before paying for the ticket. Read back as `ticket.pay_later`."},"asks_rsvp":{"type":"boolean"},"rsvp_options":{"type":["array","null"],"items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"counts_as":{"type":"string","enum":["attending","maybe","declined"]}},"required":["id","label","counts_as"]}},"visibility":{"type":"string","enum":["public","invite_only","internal"]},"transport_note":{"type":["string","null"]},"audience_tags":{"type":"array","items":{"type":"string"}},"audience_property_ids":{"type":"array","items":{"type":"string","pattern":"^prp_.+$"}},"transport_legs":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"location":{"type":"string"},"time":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"note":{"type":["string","null"]},"audience_tags":{"type":"array","items":{"type":"string"}},"audience_properties":{"type":"array","items":{"type":"string","pattern":"^prp_.+$"}},"audience_undecided":{"type":"boolean"}},"required":["id","location","time","note","audience_tags","audience_properties"]}},"sort_order":{"type":"integer"},"seating_not_required":{"type":"boolean"}}},"example":{"transport_note":"Bus at 17:30"}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Event"}},"required":["data"]},"example":{"data":{"id":"evt_01J8EVENT","name":"Welcome dinner","type":"welcome_dinner","starts_at":"2027-06-13T18:00:00.000Z","ends_at":null,"all_day":false,"venue":{"name":"The terrace","address":null,"latitude":null,"longitude":null},"description":null,"images":[],"dress_code_id":null,"meal_selection":{"enabled":false,"deadline":null,"options":[]},"ticket":{"required":false,"price":null,"pay_later":false},"rsvp":{"asks_separately":true,"options":null},"visibility":"public","audience_tags":[],"audience_property_ids":[],"transport_note":null,"transport_legs":[],"sort_order":0,"seating_not_required":false,"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"operationId":"deleteEvent","tags":["Events"],"security":[{"bearerAuth":[]}],"description":"Retrying after success returns not-found because the resource is already gone.","parameters":[{"name":"event_id","in":"path","required":true,"description":"An evt_-prefixed event id.","schema":{"type":"string","pattern":"^evt_.+$"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeletedResource"}},"required":["data"]},"example":{"data":{"id":"evt_01J8EVENT"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/events/{event_id}/invitations":{"get":{"operationId":"listEventInvitations","tags":["Events"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"event_id","in":"path","required":true,"description":"An evt_-prefixed event id.","schema":{"type":"string","pattern":"^evt_.+$"}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A cursor-paged collection.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EventInvitation"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"example":{"data":[{"id":"inv_01J8INVITE","guest_id":"gst_01J8GUEST","first_name":"Ari","last_name":"Stone"}],"has_more":false,"next_cursor":null}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"operationId":"replaceEventInvitations","tags":["Events"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","parameters":[{"name":"event_id","in":"path","required":true,"description":"An evt_-prefixed event id.","schema":{"type":"string","pattern":"^evt_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"guest_ids":{"type":"array","items":{"type":"string","pattern":"^gst_.+$"}}},"required":["guest_ids"]},"example":{"guest_ids":["gst_01J8GUEST"]}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EventInvitation"}}},"required":["data"]},"example":{"data":[{"id":"inv_01J8INVITE","guest_id":"gst_01J8GUEST","first_name":"Ari","last_name":"Stone"}]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/dress-codes":{"get":{"operationId":"listDressCodes","tags":["Dress codes"],"security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A cursor-paged collection.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DressCode"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"example":{"data":[{"id":"drc_01J8DRESS","name":"Garden formal","description_ladies":null,"pinterest_url_ladies":null,"description_men":null,"pinterest_url_men":null,"inspiration_images":[],"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}],"has_more":false,"next_cursor":null}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"createDressCode","tags":["Dress codes"],"security":[{"bearerAuth":[]}],"description":"Retry is not safe after a lost response. List the collection before creating again.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"description_ladies":{"type":["string","null"]},"pinterest_url_ladies":{"type":["string","null"]},"description_men":{"type":["string","null"]},"pinterest_url_men":{"type":["string","null"]},"inspiration_images":{"type":"array","items":{"type":"string"}}},"required":["name"]},"example":{"name":"Garden formal"}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DressCode"}},"required":["data"]},"example":{"data":{"id":"drc_01J8DRESS","name":"Garden formal","description_ladies":null,"pinterest_url_ladies":null,"description_men":null,"pinterest_url_men":null,"inspiration_images":[],"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/dress-codes/{dress_code_id}":{"get":{"operationId":"getDressCode","tags":["Dress codes"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"dress_code_id","in":"path","required":true,"description":"A drc_-prefixed dress-code id.","schema":{"type":"string","pattern":"^drc_.+$"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DressCode"}},"required":["data"]},"example":{"data":{"id":"drc_01J8DRESS","name":"Garden formal","description_ladies":null,"pinterest_url_ladies":null,"description_men":null,"pinterest_url_men":null,"inspiration_images":[],"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"updateDressCode","tags":["Dress codes"],"security":[{"bearerAuth":[]}],"description":"Retrying with the same values is safe and converges on the same stored state.","parameters":[{"name":"dress_code_id","in":"path","required":true,"description":"A drc_-prefixed dress-code id.","schema":{"type":"string","pattern":"^drc_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"description_ladies":{"type":["string","null"]},"pinterest_url_ladies":{"type":["string","null"]},"description_men":{"type":["string","null"]},"pinterest_url_men":{"type":["string","null"]},"inspiration_images":{"type":"array","items":{"type":"string"}}}},"example":{"description_ladies":"Long or midi dresses"}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DressCode"}},"required":["data"]},"example":{"data":{"id":"drc_01J8DRESS","name":"Garden formal","description_ladies":null,"pinterest_url_ladies":null,"description_men":null,"pinterest_url_men":null,"inspiration_images":[],"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"operationId":"deleteDressCode","tags":["Dress codes"],"security":[{"bearerAuth":[]}],"description":"Retrying after success returns not-found because the resource is already gone.","parameters":[{"name":"dress_code_id","in":"path","required":true,"description":"A drc_-prefixed dress-code id.","schema":{"type":"string","pattern":"^drc_.+$"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeletedResource"}},"required":["data"]},"example":{"data":{"id":"drc_01J8DRESS"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests":{"get":{"tags":["Guests"],"operationId":"listGuests","security":[{"bearerAuth":[]}],"summary":"List guests","parameters":[{"name":"party_id","in":"query","required":false,"description":"Return guests belonging to this party public ID. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string"}}},{"name":"rsvp_status","in":"query","required":false,"description":"Return only guests with this headline RSVP status. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["pending","attending","declined","maybe"]}}},{"name":"rsvp_stage","in":"query","required":false,"description":"Return only guests at this RSVP stage. Stages are free-form, so an unused value is an empty page rather than an error. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string"}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A page of guests.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Guest"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"example":{"data":[],"has_more":false,"next_cursor":"example"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Guests"],"operationId":"createGuest","security":[{"bearerAuth":[]}],"summary":"Create a guest","description":"Creates one guest. Retry after a lost response only after listing guests to confirm whether the create landed; v1 stores no idempotency key. When the couple has enabled room-assignment emails in Stays, assigning a different room also queues an email to the eligible guest on a published site with Stay available. The guest needs their own recorded email and must not have opted out; known under-13 and declined guests are excluded. This is off by default, does not charge the guest, and does not notify previous assignments when enabled. A retry assigning the same room does not create another notice; clearing a room sends no email. Email delivery is asynchronous and may be withheld when the assignment, contact, consent or site access changes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestCreate"},"example":{"first_name":"Ada","last_name":"Lovelace"}}}},"responses":{"201":{"description":"The guest was created.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Guest"}}},"example":{"data":{"id":"gst_01J8GUEST","first_name":"Ada","last_name":"Lovelace","phone":"+14155550100","rsvp_status":"attending","tags":[],"address":{},"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/import":{"post":{"tags":["Guests"],"operationId":"importGuests","security":[{"bearerAuth":[]}],"summary":"Import guests","description":"Imports at most 200 guests per request. Send larger lists in multiple requests. Retry after a lost response only after listing guests to reconcile what landed; v1 stores no idempotency key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["guests"],"properties":{"guests":{"type":"array","minItems":1,"maxItems":200,"items":{"$ref":"#/components/schemas/GuestImportRow"}}}},"example":{"guests":[{"first_name":"Ada","last_name":"Lovelace"}]}}}},"responses":{"201":{"description":"Import results, including skipped rows and errors.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GuestImportResult"}}},"example":{"data":{"imported":1,"skipped":0,"errors":[],"with_email":1,"with_phone":1,"with_address":0,"with_language":0}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/bulk":{"patch":{"tags":["Guests"],"operationId":"updateGuestsBulk","security":[{"bearerAuth":[]}],"summary":"Update up to 200 guests","description":"Updates run in order and stop on the first refusal. The result reports every requested row as updated, failed, or not attempted. Retry of the same value-setting patches converges, but read after a lost response to locate the stop point. When the couple has enabled room-assignment emails in Stays, assigning a different room also queues an email to the eligible guest on a published site with Stay available. The guest needs their own recorded email and must not have opted out; known under-13 and declined guests are excluded. This is off by default, does not charge the guest, and does not notify previous assignments when enabled. A retry assigning the same room does not create another notice; clearing a room sends no email. Email delivery is asynchronous and may be withheld when the assignment, contact, consent or site access changes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["updates"],"properties":{"updates":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","additionalProperties":false,"required":["guest_id","patch"],"properties":{"guest_id":{"$ref":"#/components/schemas/GuestId"},"patch":{"$ref":"#/components/schemas/GuestPatch"}}}}}},"example":{"updates":[{"guest_id":"gst_01J8GUEST","patch":{"first_name":"Ada"}}]}}}},"responses":{"200":{"description":"The ordered bulk result.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GuestBulkResult"}}},"example":{"data":{"ok":true,"patched":1,"total":1,"results":[{"guest_id":"gst_01J8GUEST","status":"updated"}]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}}],"get":{"tags":["Guests"],"operationId":"getGuest","security":[{"bearerAuth":[]}],"summary":"Get a guest","responses":{"200":{"description":"The guest.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Guest"}}},"example":{"data":{"id":"gst_01J8GUEST","first_name":"Ada","last_name":"Lovelace","phone":"+14155550100","rsvp_status":"attending","tags":[],"address":{},"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Guests"],"operationId":"updateGuest","security":[{"bearerAuth":[]}],"summary":"Update a guest","description":"Routes through the canonical guest patch rules. Retry with the same value-setting patch converges on the same guest state. When the couple has enabled room-assignment emails in Stays, assigning a different room also queues an email to the eligible guest on a published site with Stay available. The guest needs their own recorded email and must not have opted out; known under-13 and declined guests are excluded. This is off by default, does not charge the guest, and does not notify previous assignments when enabled. A retry assigning the same room does not create another notice; clearing a room sends no email. Email delivery is asynchronous and may be withheld when the assignment, contact, consent or site access changes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestPatch"},"example":{"first_name":"Ada"}}}},"responses":{"200":{"description":"The updated guest.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Guest"}}},"example":{"data":{"id":"gst_01J8GUEST","first_name":"Ada","last_name":"Lovelace","phone":"+14155550100","rsvp_status":"attending","tags":[],"address":{},"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Guests"],"operationId":"deleteGuest","security":[{"bearerAuth":[]}],"summary":"Delete a guest","description":"Deletes the named guest. Retry after a successful delete returns not found because the guest is already gone.","responses":{"204":{"description":"The guest was deleted."},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}/rsvp":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}}],"get":{"tags":["RSVP"],"operationId":"getGuestRsvp","security":[{"bearerAuth":[]}],"summary":"Get a guest reply","responses":{"200":{"description":"The headline reply, answers, and event responses.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GuestRsvp"}}},"example":{"data":{"guest_id":"gst_01J8GUEST","status":"attending","stage":"full","responded_at":"2026-08-31T12:00:00.000Z","option_id":null,"option_label":null,"answers":{},"event_responses":[]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"tags":["RSVP"],"operationId":"putGuestRsvp","security":[{"bearerAuth":[]}],"summary":"Record a guest reply","description":"The headline reply fans out through Aisle attendance rules and commits with event answers in one transaction. A ticketed event still requires a completed ticket payment, unless the couple has let that ticket be paid later (`Event.ticket.pay_later`). Retrying the same body converges on the same RSVP state; v1 does not persist a general idempotency key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestRsvpInput"},"example":{"status":"attending","event_responses":[]}}}},"responses":{"200":{"description":"The stored reply.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GuestRsvp"}}},"example":{"data":{"guest_id":"gst_01J8GUEST","status":"attending","stage":"full","responded_at":"2026-08-31T12:00:00.000Z","option_id":null,"option_label":null,"answers":{},"event_responses":[]}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}/site":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}}],"get":{"tags":["Guests"],"operationId":"getPersonalizedGuestSite","security":[{"bearerAuth":[]}],"summary":"Get the site as one named guest","description":"Returns only events, replies, invitations, and the room visible to the named guest. This endpoint has no anonymous or first-guest fallback.","responses":{"200":{"description":"The personalized site payload.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PersonalizedGuestSite"}}},"example":{"data":{"guest":{"id":"gst_01J8GUEST","first_name":"Ada","last_name":"Lovelace","rsvp_status":"attending","rsvp_stage":"full","rsvp_responded_at":"2026-08-31T12:00:00.000Z","dietary_restrictions":null,"dietary_notes":null,"accommodation_id":null,"language":"en"},"site":{},"events":[],"rsvp":{"guest_id":"gst_01J8GUEST","status":"attending","stage":"full","responded_at":"2026-08-31T12:00:00.000Z","option_id":null,"option_label":null,"answers":{},"event_responses":[]},"invitations":[],"room":null}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}/plus-ones":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}}],"post":{"tags":["Guests"],"operationId":"createGuestPlusOne","security":[{"bearerAuth":[]}],"summary":"Name one granted plus-one seat","description":"Creates one companion and applies the existing allowance, party, invitation, capacity, and RSVP fan-out rules. Retry after a lost response only after GET /guests to reconcile rows whose plus_one_for_guest_id equals the inviter guest id; v1 stores no idempotency key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["full_name"],"properties":{"full_name":{"type":"string","minLength":1,"maxLength":120},"phone":{"type":"string"},"phone_country":{"type":"string","enum":["AC","AD","AE","AF","AG","AI","AL","AM","AO","AR","AS","AT","AU","AW","AX","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BL","BM","BN","BO","BQ","BR","BS","BT","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CW","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","GA","GB","GD","GE","GF","GG","GH","GI","GL","GM","GN","GP","GQ","GR","GT","GU","GW","GY","HK","HN","HR","HT","HU","ID","IE","IL","IM","IN","IO","IQ","IR","IS","IT","JE","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","ME","MF","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PR","PS","PT","PW","PY","QA","RE","RO","RS","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","SS","ST","SV","SX","SY","SZ","TA","TC","TD","TG","TH","TJ","TK","TL","TM","TN","TO","TR","TT","TV","TW","TZ","UA","UG","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","XK","YE","YT","ZA","ZM","ZW"],"description":"Optional ISO country code for a national phone number. An explicit international calling code takes precedence."},"email":{"type":"string","format":"email"}}},"example":{"full_name":"example"}}}},"responses":{"201":{"description":"The companion guest was created.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Guest"}}},"example":{"data":{"id":"gst_01J8GUEST","first_name":"Ada","last_name":"Lovelace","phone":"+14155550100","rsvp_status":"attending","tags":[],"address":{},"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}/room":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}}],"put":{"tags":["Guests"],"operationId":"putGuestRoom","security":[{"bearerAuth":[]}],"summary":"Assign or clear a guest room","description":"Routes through the canonical guest patch and room ownership checks. Retry with the same room id converges on the same assignment. When the couple has enabled room-assignment emails in Stays, assigning a different room also queues an email to the eligible guest on a published site with Stay available. The guest needs their own recorded email and must not have opted out; known under-13 and declined guests are excluded. This is off by default, does not charge the guest, and does not notify previous assignments when enabled. A retry assigning the same room does not create another notice; clearing a room sends no email. Email delivery is asynchronous and may be withheld when the assignment, contact, consent or site access changes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["accommodation_id"],"properties":{"accommodation_id":{"oneOf":[{"$ref":"#/components/schemas/AccommodationId"},{"type":"null"}]}}},"example":{"accommodation_id":"acc_01J8ROOM"}}}},"responses":{"200":{"description":"The updated guest.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Guest"}}},"example":{"data":{"id":"gst_01J8GUEST","first_name":"Ada","last_name":"Lovelace","phone":"+14155550100","rsvp_status":"attending","tags":[],"address":{},"created_at":"2026-08-31T12:00:00.000Z","updated_at":"2026-08-31T12:00:00.000Z"}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}/event-invitations":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}}],"get":{"tags":["RSVP"],"operationId":"listGuestEventInvitations","security":[{"bearerAuth":[]}],"summary":"List explicit event invitations for a guest","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The guest invitation rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GuestInvitation"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"example":{"data":[],"has_more":false,"next_cursor":"example"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guests/{guest_id}/event-invitations/{event_id}":{"parameters":[{"name":"guest_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gst_.+$"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","pattern":"^evt_.+$"}}],"put":{"tags":["RSVP"],"operationId":"putGuestEventInvitation","security":[{"bearerAuth":[]}],"summary":"Set one explicit event invitation","description":"Sets the invitation membership and preserves RSVP fan-out. Retry with the same invited value converges on the same invitation state.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["invited"],"properties":{"invited":{"type":"boolean"}}},"example":{"invited":false}}}},"responses":{"200":{"description":"The invitation state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GuestInvitation"}}},"example":{"data":{"event_id":"evt_01J8EVENT","invited":true}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/parties":{"get":{"tags":["Parties"],"operationId":"listParties","summary":"List parties","security":[{"bearerAuth":[]}],"description":"Includes unnamed existing parties and empty parties retained for stable identity and room history. Requires read scope and preview access.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A page of parties.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Party"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Parties"],"operationId":"createParty","summary":"Create a party","description":"Creates a party and moves the supplied guests into it atomically. The first supplied guest leads and keeps their RSVP; later members inherit that reply. Empty and single-member parties are allowed. Duplicate guest IDs are refused. A missing or foreign guest, or an active accommodation payment, rolls back the entire operation. Requires write scope and preview access.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartyCreate"}}}},"responses":{"201":{"description":"The party and its current membership.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Party"}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/parties/{party_id}":{"parameters":[{"name":"party_id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/PartyId"}}],"get":{"tags":["Parties"],"operationId":"getParty","summary":"Read a party","security":[{"bearerAuth":[]}],"description":"Returns only a party belonging to the API key wedding. Requires read scope and preview access.","responses":{"200":{"description":"The party and its current membership.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Party"}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Parties"],"operationId":"updateParty","summary":"Rename a party","description":"Changes only the name. Null or whitespace clears it. Does not change membership, replies or identity. Requires write scope and preview access.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartyPatch"}}}},"responses":{"200":{"description":"The party and its current membership.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Party"}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/parties/{party_id}/guests/{guest_id}":{"parameters":[{"name":"party_id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/PartyId"}},{"name":"guest_id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/GuestId"}}],"put":{"tags":["Parties"],"operationId":"addPartyMember","summary":"Join a party","description":"Moves an existing guest into this party. A new member inherits the lead RSVP and stage; joining an empty party preserves their reply and makes them lead. Repeating an existing membership preserves the reply and leadership. Repairs both parties. Requires write scope and preview access. No request body.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The party and its current membership.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Party"}}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Parties"],"operationId":"removePartyMember","summary":"Leave a party","security":[{"bearerAuth":[]}],"description":"Unlinks this member without deleting the guest, the party or their answers. Promotes a replacement lead when needed. A guest outside this party returns 404. Active accommodation payments return 409. Requires write scope and preview access. No request body.","responses":{"204":{"description":"The guest has left the party."},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guest-access":{"get":{"tags":["Guest access"],"operationId":"listGuestAccess","summary":"List invitation access","description":"Returns active, expired and revoked credential metadata, never codes or sessions. Requires read scope and preview access.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"A page of access credentials.","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GuestAccess"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}]},"post":{"tags":["Guest access"],"operationId":"createGuestAccess","summary":"Create an invitation code","description":"Supply one guest ID for individual access or multiple guest IDs for a shared group. Every guest must belong to the API key wedding. Membership does not change parties, invitations or replies. The generated code is shown once; save it securely for the invitation. Requires write scope and preview access. No idempotency key is stored: after a lost response list and reconcile, then rotate the matching credential to recover access rather than blindly creating another.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestAccessCreate"}}}},"responses":{"201":{"description":"Create an invitation code","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/GuestAccessIssued"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guest-access/{access_id}":{"parameters":[{"name":"access_id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/GuestAccessId"}}],"get":{"tags":["Guest access"],"operationId":"getGuestAccess","summary":"Read invitation access","description":"Reads credential metadata and surviving guest membership in the API key wedding. Requires read scope and preview access. A public resource ID does not authenticate a guest.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Read invitation access","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/GuestAccess"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Guest access"],"operationId":"updateGuestAccess","summary":"Update invitation access","description":"Replace guest_ids or expires_at to invalidate all existing sessions. A name-only change preserves sessions. Null clears name or expiry. Revoked access cannot be edited. Requires write scope and preview access.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestAccessPatch"}}}},"responses":{"200":{"description":"Update invitation access","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/GuestAccess"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Guest access"],"operationId":"revokeGuestAccess","summary":"Revoke invitation access","description":"The code and all sessions stop verifying. Repeating revocation returns 204. Guest records and RSVP Parties are preserved. Requires write scope and preview access.","security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Access revoked.","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guest-access/{access_id}/rotate":{"parameters":[{"name":"access_id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/GuestAccessId"}}],"post":{"tags":["Guest access"],"operationId":"rotateGuestAccess","summary":"Replace an invitation code","description":"Shows a new code once and invalidates the previous code and all sessions. Revoked access cannot be rotated. Requires write scope and preview access. No body. After a lost response a deliberate repeat issues another new code.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Replace an invitation code","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/GuestAccessIssued"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guest-access/verify":{"post":{"tags":["Guest access"],"operationId":"verifyGuestAccessCode","summary":"Exchange an invitation code for a session","description":"Call from your server with its wedding API key. Requires read scope and preview access. Codes ignore case, ASCII spaces and hyphens. Incorrect, foreign, expired, revoked or empty-membership codes return the same 401 error. Existing durable quotas apply before verification: 120 requests per API key and 600 per wedding per minute, including incorrect codes. The session expires after at most 2592000 seconds or at credential expiry. Keep it in an HttpOnly cookie on your own origin and verify it before every protected request.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestAccessVerify"}}}},"responses":{"200":{"description":"Exchange an invitation code for a session","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/GuestAccessSessionIssued"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guest-access/sessions/verify":{"post":{"tags":["Guest access"],"operationId":"verifyGuestAccessSession","summary":"Verify a current guest session","description":"Requires read scope and preview access. Checks the signed session, its wedding, expiry, current credential version, revocation and surviving members. Supply guest_id before reading or writing for a selected guest; a guest outside the grant is forbidden. Membership or expiry changes and rotation invalidate prior sessions. Returns current access without echoing the session token. This endpoint does not make the broad wedding API key guest-scoped; your server must enforce this result before each existing guest endpoint call.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestAccessSessionVerify"}}}},"responses":{"200":{"description":"Verify a current guest session","headers":{"Cache-Control":{"description":"Credential and session responses must not be cached.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/GuestAccessSession"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/properties":{"get":{"tags":["Stays"],"summary":"List properties","description":"Places arrive in the order the couple put them in, the same order their own wedding site reads them in. Render them as they arrive; re-sorting by name shows guests a different order than the couple set.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Stays"],"summary":"Create a property","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"arrangement":{"type":"string","enum":["hosted_rooms","room_block","recommended"]},"room_selection_mode":{"anyOf":[{"type":"string","enum":["couple_assigned","guest_choice"]},{"type":"null"}],"description":"Room choice for this property. A non-null value requires hosted_rooms. Null inherits the wedding legacy mode; omit on PATCH to preserve the current override."},"address":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]},"place_id":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"latitude":{"anyOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"longitude":{"anyOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:\\d?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"images":{"maxItems":6,"type":"array","items":{"type":"string","pattern":"^https:\\/\\/"},"description":"Ordered hotel photo URLs. Omit to preserve existing photos; send an empty list to clear them. Room photos are separate."},"booking_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"default_check_in_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"default_check_out_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"default_check_in_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"default_check_out_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"default_check_in_notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"block_rooms_held":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"block_booking_deadline":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"block_code":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"audience_tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"price_unit":{"type":"string","enum":["room","night","party","head"]},"price_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_unit":{"type":"string","enum":["percent","amount"]},"deposit_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"balance_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/properties/{property_id}":{"get":{"tags":["Stays"],"summary":"Get a property","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prp_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Stays"],"summary":"Update a property","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prp_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"arrangement":{"type":"string","enum":["hosted_rooms","room_block","recommended","self_arranged"]},"room_selection_mode":{"anyOf":[{"type":"string","enum":["couple_assigned","guest_choice"]},{"type":"null"}],"description":"Room choice for this property. A non-null value requires hosted_rooms. Null inherits the wedding legacy mode; omit on PATCH to preserve the current override."},"address":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]},"place_id":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"latitude":{"anyOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"longitude":{"anyOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:\\d?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"images":{"maxItems":6,"type":"array","items":{"type":"string","pattern":"^https:\\/\\/"},"description":"Ordered hotel photo URLs. Omit to preserve existing photos; send an empty list to clear them. Room photos are separate."},"booking_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"default_check_in_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"default_check_out_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"default_check_in_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"default_check_out_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"default_check_in_notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"block_rooms_held":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"block_booking_deadline":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"block_code":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"audience_tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"price_unit":{"type":"string","enum":["room","night","party","head"]},"price_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_unit":{"type":"string","enum":["percent","amount"]},"deposit_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"balance_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Stays"],"summary":"Delete a property","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prp_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/properties/{property_id}/rooms":{"get":{"tags":["Stays"],"summary":"List rooms in a property","description":"Rates, due dates, booking URLs, and stay details include values inherited from the property through Aisle’s canonical stay models.","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prp_.+$"}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Stays"],"summary":"Create a room","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prp_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"type":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"capacity":{"type":"integer","minimum":1,"maximum":50},"capacity_max":{"anyOf":[{"type":"integer","minimum":1,"maximum":50},{"type":"null"}]},"bed_config":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"images":{"maxItems":6,"type":"array","items":{"type":"string","pattern":"^https:\\/\\/"}},"check_in_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"check_out_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"check_in_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"check_out_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"check_in_notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"booking_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"price_unit":{"type":"string","enum":["room","night","party","head"]},"price_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_unit":{"type":"string","enum":["percent","amount"]},"deposit_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"balance_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"requires_payment":{"type":"boolean"},"status":{"type":"string","enum":["available","unavailable"]}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/rooms":{"get":{"tags":["Stays"],"summary":"List all rooms","description":"The complete active wedding room inventory, including legacy rooms and rooms whose property was deleted. Removed rooms are excluded even when retained internally for checkout or payment history. Use this collection to refresh a local room index; the nested property collection remains available for property-scoped views.","parameters":[{"name":"status","in":"query","required":false,"description":"Return only rooms with this availability. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["available","unavailable"]}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/rooms/{room_id}":{"get":{"tags":["Stays"],"summary":"Get a room","description":"Returns an active room. A removed room returns 404, including when its internal record is retained for checkout or payment history.","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","pattern":"^acc_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Stays"],"summary":"Update a room","description":"Validates every field, including a property move, before one wedding-scoped room update. A room with an accommodation payment in progress returns 409 conflict. Retrying the same body converges on the same room state; v1 does not persist a general idempotency key.","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","pattern":"^acc_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"type":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"capacity":{"type":"integer","minimum":1,"maximum":50},"capacity_max":{"anyOf":[{"type":"integer","minimum":1,"maximum":50},{"type":"null"}]},"bed_config":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"images":{"maxItems":6,"type":"array","items":{"type":"string","pattern":"^https:\\/\\/"}},"check_in_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"check_out_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"check_in_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"check_out_time":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"check_in_notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"booking_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"price_unit":{"type":"string","enum":["room","night","party","head"]},"price_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_unit":{"type":"string","enum":["percent","amount"]},"deposit_amount":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":100000,"multipleOf":0.01},{"type":"string","pattern":"^(?:\\d{1,5}(?:\\.\\d{1,2})?|100000(?:\\.0{1,2})?)$"}]},{"type":"null"}]},"deposit_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"balance_due_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"requires_payment":{"type":"boolean"},"status":{"type":"string","enum":["available","unavailable"]},"property_id":{"type":"string","pattern":"^prp_.+"}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Stays"],"summary":"Delete a room","description":"Removes a room from active inventory and clears its guest assignments. Cancellation is attempted only after Stripe reports no payment method and no charge; removing a room with a checkout requires confirmed cancellation. Checkout and payment history is retained, including the internal room record when needed by its ledger. Completed or refunded payments, processing payments, active checkouts with a card entered, and checkouts whose cancellation cannot be confirmed return 409 conflict. A payment record or an active or Stripe-linked checkout attempt on another room covered by the same household charge also returns 409; deleting one room never cancels another room's checkout. A successful deletion returns 204; subsequent room reads return 404.","parameters":[{"name":"room_id","in":"path","required":true,"schema":{"type":"string","pattern":"^acc_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/airports":{"get":{"tags":["Travel"],"summary":"List airports","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirportList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Travel"],"summary":"Create an airport","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"code":{"type":"string","minLength":1,"maxLength":10},"country":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"travel_time_to_venue":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"required":["name","code"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirportResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/airports/{airport_id}":{"get":{"tags":["Travel"],"summary":"Get an airport","parameters":[{"name":"airport_id","in":"path","required":true,"schema":{"type":"string","pattern":"^air_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirportResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Travel"],"summary":"Update an airport","parameters":[{"name":"airport_id","in":"path","required":true,"schema":{"type":"string","pattern":"^air_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"code":{"type":"string","minLength":1,"maxLength":10},"country":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"travel_time_to_venue":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AirportResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Travel"],"summary":"Delete an airport","parameters":[{"name":"airport_id","in":"path","required":true,"schema":{"type":"string","pattern":"^air_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/airports/{airport_id}/transport-options":{"get":{"tags":["Travel"],"summary":"List airport transport options","parameters":[{"name":"airport_id","in":"path","required":true,"schema":{"type":"string","pattern":"^air_.+$"}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransportOptionList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Travel"],"summary":"Create an airport transport option","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","parameters":[{"name":"airport_id","in":"path","required":true,"schema":{"type":"string","pattern":"^air_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"mode":{"type":"string","enum":["shuttle","rental_car","train","taxi","walking"]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"estimated_cost":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"estimated_time":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"booking_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"provided":{"type":"boolean"},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"required":["name","mode"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransportOptionResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/transport-options/{transport_option_id}":{"patch":{"tags":["Travel"],"summary":"Update a transport option","parameters":[{"name":"transport_option_id","in":"path","required":true,"schema":{"type":"string","pattern":"^trn_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"airport_id":{"type":"string","pattern":"^air_.+"},"name":{"type":"string","minLength":1,"maxLength":200},"mode":{"type":"string","enum":["shuttle","rental_car","train","taxi","walking"]},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"estimated_cost":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"estimated_time":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"booking_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"provided":{"type":"boolean"},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransportOptionResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Travel"],"summary":"Delete a transport option","parameters":[{"name":"transport_option_id","in":"path","required":true,"schema":{"type":"string","pattern":"^trn_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/recommendations":{"get":{"tags":["Recommendations"],"summary":"List recommendations","parameters":[{"name":"category","in":"query","required":false,"description":"Return only recommendations in this category. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["hotel","food","activity","sight"]}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Recommendations"],"summary":"Create a recommendation","description":"Category defaults to activity when omitted. New rows may be food, activity, or sight. Difficulty may be non-null only for activity or sight. Create lodging through properties and rooms.\n\nThis POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"details_html":{"anyOf":[{"type":"string","maxLength":20000},{"type":"null"}]},"emoji":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"category":{"type":"string","enum":["food","activity","sight"],"description":"A new target category: food, activity, or sight. Hotel is legacy response compatibility; create lodging through properties and rooms."},"difficulty":{"anyOf":[{"type":"string","enum":["easy","moderate","challenging"]},{"type":"null"}],"description":"May be non-null only when the resulting category is activity or sight."},"external_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"latitude":{"anyOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"longitude":{"anyOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:\\d?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"place_id":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"audience_tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"required":["name"],"additionalProperties":false,"allOf":[{"if":{"properties":{"category":{"const":"food"}},"required":["category"]},"then":{"properties":{"difficulty":{"type":"null"}}}}]}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/recommendations/{recommendation_id}":{"get":{"tags":["Recommendations"],"summary":"Get a recommendation","parameters":[{"name":"recommendation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^rec_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Recommendations"],"summary":"Update a recommendation","description":"Category may target food, activity, or sight. A non-null difficulty requires the resulting stored category to be activity or sight, and moving a row to food clears difficulty. Legacy hotel rows remain editable only when category is omitted; lodging belongs in properties and rooms.","parameters":[{"name":"recommendation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^rec_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"details_html":{"anyOf":[{"type":"string","maxLength":20000},{"type":"null"}]},"emoji":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"category":{"type":"string","enum":["food","activity","sight"],"description":"A new target category: food, activity, or sight. Hotel is legacy response compatibility; create lodging through properties and rooms."},"difficulty":{"anyOf":[{"type":"string","enum":["easy","moderate","challenging"]},{"type":"null"}],"description":"May be non-null only when the resulting category is activity or sight."},"external_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"latitude":{"anyOf":[{"type":"number","minimum":-90,"maximum":90,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:[0-8]?\\d(?:\\.\\d{1,7})?|90(?:\\.0{1,7})?)$"},{"type":"null"}]},"longitude":{"anyOf":[{"type":"number","minimum":-180,"maximum":180,"multipleOf":1e-7},{"type":"string","pattern":"^-?(?:(?:\\d?\\d|1[0-7]\\d)(?:\\.\\d{1,7})?|180(?:\\.0{1,7})?)$"},{"type":"null"}]},"place_id":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"audience_tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Recommendations"],"summary":"Delete a recommendation","parameters":[{"name":"recommendation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^rec_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/faqs":{"get":{"tags":["Recommendations"],"summary":"List FAQs","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaqList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Recommendations"],"summary":"Create an FAQ","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":5000},"answer":{"type":"string","minLength":1,"maxLength":5000},"emoji":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"required":["question","answer"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaqResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/faqs/{faq_id}":{"get":{"tags":["Recommendations"],"summary":"Get an FAQ","parameters":[{"name":"faq_id","in":"path","required":true,"schema":{"type":"string","pattern":"^faq_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaqResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Recommendations"],"summary":"Update an FAQ","parameters":[{"name":"faq_id","in":"path","required":true,"schema":{"type":"string","pattern":"^faq_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":5000},"answer":{"type":"string","minLength":1,"maxLength":5000},"emoji":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"sort_order":{"type":"integer","minimum":0,"maximum":100000}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaqResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Recommendations"],"summary":"Delete an FAQ","parameters":[{"name":"faq_id","in":"path","required":true,"schema":{"type":"string","pattern":"^faq_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/registry/items":{"get":{"tags":["Registry"],"summary":"List registry items","description":"Every received amount and gift count comes from completed, unrefunded payments.","parameters":[{"name":"active","in":"query","required":false,"description":"Return only items with this active flag. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["true","false"]}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItemList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Registry"],"summary":"Create a registry item","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"image_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"goal_amount":{"anyOf":[{"type":"number","minimum":0,"maximum":99999999.99,"multipleOf":0.01},{"type":"string","pattern":"^\\d{1,8}(?:\\.\\d{1,2})?$"}]},"unit_label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"unit_price":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":99999999.99,"multipleOf":0.01},{"type":"string","pattern":"^\\d{1,8}(?:\\.\\d{1,2})?$"}]},{"type":"null"}]},"unit_count":{"anyOf":[{"type":"integer","minimum":1,"maximum":100000},{"type":"null"}]},"allow_custom_amount":{"type":"boolean"},"sort_order":{"type":"integer","minimum":0,"maximum":100000},"active":{"type":"boolean"}},"required":["title","goal_amount"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItemResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/registry/items/{registry_item_id}":{"get":{"tags":["Registry"],"summary":"Get a registry item","parameters":[{"name":"registry_item_id","in":"path","required":true,"schema":{"type":"string","pattern":"^reg_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItemResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Registry"],"summary":"Update a registry item","parameters":[{"name":"registry_item_id","in":"path","required":true,"schema":{"type":"string","pattern":"^reg_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"image_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"goal_amount":{"anyOf":[{"type":"number","minimum":0,"maximum":99999999.99,"multipleOf":0.01},{"type":"string","pattern":"^\\d{1,8}(?:\\.\\d{1,2})?$"}]},"unit_label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"unit_price":{"anyOf":[{"anyOf":[{"type":"number","minimum":0,"maximum":99999999.99,"multipleOf":0.01},{"type":"string","pattern":"^\\d{1,8}(?:\\.\\d{1,2})?$"}]},{"type":"null"}]},"unit_count":{"anyOf":[{"type":"integer","minimum":1,"maximum":100000},{"type":"null"}]},"allow_custom_amount":{"type":"boolean"},"sort_order":{"type":"integer","minimum":0,"maximum":100000},"active":{"type":"boolean"}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItemResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Registry"],"summary":"Delete a registry item","description":"Deletes the item through Aisle’s registry deletion policy. Payment ledger rows are retained and detached.","parameters":[{"name":"registry_item_id","in":"path","required":true,"schema":{"type":"string","pattern":"^reg_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/registry/contributions":{"get":{"tags":["Registry"],"summary":"List settled registry contributions","description":"Requires a payments-scoped key and full membership access. Only completed, unrefunded contribution payments are returned. Anonymous gifts have null guest_id and contributor_name fields.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryContributionList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/registry/summary":{"get":{"tags":["Registry"],"summary":"Get registry totals","description":"Totals use the settled payment ledger. Stored registry current_amount values are not used.","responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrySummaryResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/uploads":{"post":{"tags":["Media"],"summary":"Create constrained upload instructions","description":"Request a short-lived image upload token through your own same-origin server proxy. The proxy adds the server-only Aisle bearer key when forwarding this request. Never embed that key in client JavaScript. In the browser, build `const pathname = 'weddings/photos/' + wedding.data.id + '/api/' + file.name` and call `upload(pathname, file, { access: 'public', handleUploadUrl: '/api/aisle-upload' })`; use the corresponding `weddings/site/cover/` prefix for a cover. Here `wedding.data.id` is the public ID returned by `GET /wedding`. After upload, register the URL with `POST /photos` or `PATCH /site/cover`. The signed provider callback is internal to Aisle.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["type","payload"],"properties":{"type":{"const":"blob.generate-client-token"},"payload":{"type":"object","additionalProperties":false,"required":["pathname","multipart","clientPayload"],"properties":{"pathname":{"type":"string","description":"Use weddings/photos/{public_wedding_id}/api/ for photos or weddings/site/cover/{public_wedding_id}/api/ for a cover. Substitute the public ID returned by GET /wedding in data.id."},"multipart":{"type":"boolean"},"clientPayload":{"oneOf":[{"type":"string"},{"type":"null"}]}}}},"example":{"type":"blob.generate-client-token","payload":{"pathname":"weddings/photos/wed_example/api/photo.jpg","multipart":false,"clientPayload":null}}}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicUploadInstructions"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/photos":{"get":{"tags":["Media"],"summary":"List gallery photos","description":"Returns stable media URLs and dimensions, without exposing storage credentials or internal blob records.","parameters":[{"name":"section","in":"query","required":false,"description":"Return only photos in this gallery section. Sections are free-form, so an unused key is an empty page rather than an error. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string"}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Media"],"summary":"Register uploaded gallery photos","description":"Registers one to sixty Vercel Blob URLs created under this wedding’s signed photo prefix.\n\nThis POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","pattern":"^https:\\/\\/"},"width":{"type":"integer","minimum":1,"maximum":100000},"height":{"type":"integer","minimum":1,"maximum":100000},"section":{"type":"string","minLength":1,"maxLength":50},"captured_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["url","width","height"],"additionalProperties":false},{"type":"object","properties":{"photos":{"minItems":1,"maxItems":60,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","pattern":"^https:\\/\\/"},"width":{"type":"integer","minimum":1,"maximum":100000},"height":{"type":"integer","minimum":1,"maximum":100000},"section":{"type":"string","minLength":1,"maxLength":50},"captured_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["url","width","height"],"additionalProperties":false}}},"required":["photos"],"additionalProperties":false}]}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoRegistrationResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/photos/{photo_id}":{"delete":{"tags":["Media"],"summary":"Delete a gallery photo record","parameters":[{"name":"photo_id","in":"path","required":true,"schema":{"type":"string","pattern":"^pho_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/site/cover":{"get":{"tags":["Media"],"summary":"Get the site cover","responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Media"],"summary":"Set or clear the site cover","description":"A non-null cover URL must come from this wedding’s signed cover upload prefix.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]}},"required":["url"],"additionalProperties":false}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guestbook":{"get":{"tags":["Guest content"],"summary":"List guestbook entries","parameters":[{"name":"approved","in":"query","required":false,"description":"Return only entries with this moderation state. Repeat the parameter, or comma-separate its values, to match any of them.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["true","false"]}}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestbookEntryList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Guest content"],"summary":"Create a guestbook entry","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"guest_id":{"type":"string","pattern":"^gst_.+"},"message":{"type":"string","minLength":1,"maxLength":500},"approved":{"type":"boolean"}},"required":["guest_id","message"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestbookEntryResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/guestbook/{guestbook_id}":{"patch":{"tags":["Guest content"],"summary":"Moderate a guestbook entry","parameters":[{"name":"guestbook_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gbk_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"approved":{"type":"boolean"}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestbookEntryResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Guest content"],"summary":"Delete a guestbook entry","parameters":[{"name":"guestbook_id","in":"path","required":true,"schema":{"type":"string","pattern":"^gbk_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/songs":{"get":{"tags":["Guest content"],"summary":"List song requests","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SongRequestList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Guest content"],"summary":"Create a song request","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"guest_id":{"type":"string","pattern":"^gst_.+"},"title":{"type":"string","minLength":1,"maxLength":500},"artist":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"spotify_track_id":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"album_art_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]},"preview_url":{"anyOf":[{"type":"string","pattern":"^https:\\/\\/"},{"type":"null"}]}},"required":["guest_id","title"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SongRequestResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/songs/{song_id}":{"delete":{"tags":["Guest content"],"summary":"Delete a song request","parameters":[{"name":"song_id","in":"path","required":true,"schema":{"type":"string","pattern":"^sng_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/predictions":{"get":{"tags":["Guest content"],"summary":"List predictions","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Guest content"],"summary":"Create a prediction","description":"This POST has no idempotency-key store. After a lost response, list before retrying, reconcile the resource, and retry only deliberately.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":1000},"options":{"minItems":2,"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100},"label":{"type":"string","minLength":1,"maxLength":300}},"required":["id","label"],"additionalProperties":false}},"sort_order":{"type":"integer","minimum":0,"maximum":100000},"active":{"type":"boolean"}},"required":["question","options"],"additionalProperties":false}}}},"responses":{"201":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/predictions/{prediction_id}":{"get":{"tags":["Guest content"],"summary":"Get a prediction","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prd_.+$"}}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Guest content"],"summary":"Update a prediction","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prd_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":1000},"options":{"minItems":2,"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100},"label":{"type":"string","minLength":1,"maxLength":300}},"required":["id","label"],"additionalProperties":false}},"sort_order":{"type":"integer","minimum":0,"maximum":100000},"active":{"type":"boolean"}},"additionalProperties":false,"minProperties":1}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Guest content"],"summary":"Delete a prediction","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prd_.+$"}}],"responses":{"204":{"description":"The resource was deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/predictions/{prediction_id}/responses":{"get":{"tags":["Guest content"],"summary":"List prediction responses","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prd_.+$"}},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponseList"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Guest content"],"summary":"Create or replace a guest prediction response","description":"This guest-scoped upsert converges when the same selected_option_id is retried.","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"string","pattern":"^prd_.+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"guest_id":{"type":"string","pattern":"^gst_.+"},"selected_option_id":{"type":"string","minLength":1,"maxLength":100}},"required":["guest_id","selected_option_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponseResult"}}}},"201":{"description":"A response was created.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponseResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/stats":{"get":{"tags":["Statistics"],"summary":"Get canonical wedding statistics","description":"Guest totals use Aisle’s headcount model. Room totals use settlement groups and completed, unrefunded accommodation payments. Registry totals use completed, unrefunded registry payments.","responses":{"200":{"description":"The requested data.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeddingStatsResult"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/checkouts":{"post":{"security":[{"bearerAuth":[]}],"operationId":"createCheckout","tags":["Payments"],"summary":"Create a guest checkout","description":"Requires an API key with the payments scope and full access. Call this endpoint only from your server. Send only the returned client_secret and stripe_publishable_key to your browser, load Stripe.js with that key, mount Stripe Elements with the client secret, and call stripe.confirmPayment in the browser. The key is Aisle's: the PaymentIntent is created on Aisle's Stripe account and paid out to the couple, so a publishable key of your own cannot confirm it, and Stripe.js takes no connected account. Never send the Aisle bearer key to browser JavaScript.\n\nAisle owns admission, ticket, room, instalment, currency, status, and fee values. Only a registry contribution accepts a caller-chosen amount. Accommodation checkouts use the same durable room hold, household share, and recovery rules as Aisle's guest site.\n\nA registry contribution names an invited guest with guest_id, or carries the giver's own contributor_name and contributor_email when they are not on the guest list. Send one or the other. A gift without a guest_id needs the wedding's public_registry_enabled switch, which GET /wedding returns and PATCH /wedding sets; with the switch off the answer is 403. Stripe emails the receipt to contributor_email, and GET /registry/contributions returns the typed name.\n\nA successful response creates a pending Aisle ledger row. Stripe confirmation and Aisle settlement happen asynchronously, so poll GET /payments/{payment_id}. This POST has no general idempotency-key contract. If the response is lost, reconcile with the payment list before deliberately creating another checkout. Do not retry blindly.","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"type":{"const":"registry_contribution"},"guest_id":{"type":"string","pattern":"^gst_.+$","description":"The invited guest who is giving. Omit it for a giver who is not on the guest list, and send contributor_name and contributor_email instead."},"contributor_name":{"type":"string","minLength":1,"maxLength":120,"description":"Who to thank. Required without a guest_id, and rejected beside one."},"contributor_email":{"type":"string","format":"email","maxLength":320,"description":"Where Stripe sends the receipt. Required without a guest_id, even for an anonymous gift, and rejected beside one."},"registry_item_id":{"type":"string","pattern":"^reg_.+$"},"amount":{"oneOf":[{"type":"number","exclusiveMinimum":0,"maximum":10000,"multipleOf":0.01},{"type":"string","pattern":"^(?:(?:[1-9]\\d{0,3})(?:\\.\\d{1,2})?|10000(?:\\.0{1,2})?|0\\.(?:0[1-9]|[1-9]\\d?))$"}],"description":"The donor-chosen amount, greater than 0 and no more than 10000."},"message":{"type":["string","null"]},"is_anonymous":{"type":"boolean","default":false}},"required":["type","registry_item_id","amount"]},{"type":"object","additionalProperties":false,"properties":{"type":{"const":"accommodation"},"guest_id":{"type":"string","pattern":"^gst_.+$"},"accommodation_id":{"oneOf":[{"type":"string","pattern":"^acc_.+$"},{"type":"null"}],"description":"A room to claim in guest-choice mode. Omit it to use the guest assignment."},"pay_in_full":{"type":"boolean","default":false},"share":{"type":"boolean","default":false,"description":"When true, use the canonical household-share accommodation charge."}},"required":["type","guest_id"]},{"type":"object","additionalProperties":false,"properties":{"type":{"const":"admission"},"guest_id":{"type":"string","pattern":"^gst_.+$"}},"required":["type","guest_id"]},{"type":"object","additionalProperties":false,"properties":{"type":{"const":"ticket"},"guest_id":{"type":"string","pattern":"^gst_.+$"},"event_id":{"type":"string","pattern":"^evt_.+$"}},"required":["type","guest_id","event_id"]}],"discriminator":{"propertyName":"type"}}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Checkout"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/payments":{"get":{"security":[{"bearerAuth":[]}],"operationId":"listPayments","tags":["Payments"],"summary":"List payments","description":"Requires an API key with the payments scope. Returns the fixed public ledger projection for the key wedding.","parameters":[{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"A wedding-scoped payment page.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/payments/{payment_id}":{"get":{"security":[{"bearerAuth":[]}],"operationId":"getPayment","tags":["Payments"],"summary":"Get a payment","description":"Requires an API key with the payments scope. A payment outside the key wedding is not found.","parameters":[{"name":"payment_id","in":"path","required":true,"schema":{"type":"string","pattern":"^pay_.+$"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Payment"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/payouts/status":{"get":{"security":[{"bearerAuth":[]}],"operationId":"getPayoutStatus","tags":["Payouts"],"summary":"Get payout status","description":"Requires an API key with the payments scope. This preview-access read never exposes the Stripe account id.","responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PayoutStatus"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/payouts/onboarding-link":{"post":{"security":[{"bearerAuth":[]}],"operationId":"createPayoutOnboardingLink","tags":["Payouts"],"summary":"Create a payout onboarding link","description":"Requires an API key with the payments scope and full access. Call it from your server and redirect the couple to the returned short-lived Stripe URL. This POST uses a stable internal account-creation key, but exposes no general client idempotency-key contract.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"country":{"type":"string","description":"Payout-bank country. Unsupported values use the US default."},"email":{"type":"string","format":"email","description":"Required when creating a payout account."},"return_url":{"type":"string","format":"uri","description":"An absolute HTTPS URL. Plain HTTP is accepted only for loopback development."},"refresh_url":{"type":"string","format":"uri","description":"An absolute HTTPS URL. Plain HTTP is accepted only for loopback development."}},"required":["return_url","refresh_url"]}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PayoutLink"}},"required":["data"]}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/MembershipRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"409":{"$ref":"#/components/responses/Conflict"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A wedding-scoped API key. Send it from your own server; never from a browser."}},"parameters":{"limit":{"name":"limit","in":"query","required":false,"description":"How many records to return, 1 to 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},"cursor":{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` from the previous page. Omit for the first page.","schema":{"type":"string"}}},"headers":{"X-Request-Id":{"description":"Correlation id for this request. Quote it when reporting a problem.","schema":{"type":"string"}},"X-Aisle-Api-Version":{"description":"The API version that served this request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests permitted in the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix seconds at which the current window resets.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying a rate-limited call.","schema":{"type":"integer","minimum":1}}},"responses":{"InvalidRequest":{"description":"The request itself could not be read, such as a body that is not a JSON object. A field we refuse is validation_failed instead.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"The API key is missing, malformed, or no longer valid.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"MembershipRequired":{"description":"The operation requires an active Aisle membership for this wedding.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The key is valid but not permitted to do this.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such resource inside the key's wedding.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"MethodNotAllowed":{"description":"That HTTP method is not supported here. See the Allow header.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The request collided with the current state of the resource.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UnsupportedMediaType":{"description":"A request body must be sent as application/json.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationFailed":{"description":"The request was well-formed but a field was not acceptable. Every field at fault is named in error.details.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests. Retry after the time given in Retry-After.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Something went wrong on our side.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-Aisle-Api-Version":{"$ref":"#/components/headers/X-Aisle-Api-Version"},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error","request_id"],"additionalProperties":false,"properties":{"error":{"type":"object","required":["code","message","details"],"additionalProperties":false,"properties":{"code":{"type":"string","enum":["invalid_request","unauthorized","membership_required","forbidden","not_found","method_not_allowed","conflict","unsupported_media_type","validation_failed","rate_limited","internal_error"],"description":"Stable machine-readable failure code."},"message":{"type":"string","description":"Human-readable explanation. Wording may change; do not match on it."},"details":{"type":"array","description":"Field-level problems, one entry per field at fault. Populated for validation_failed and empty for every other code.","items":{"$ref":"#/components/schemas/ErrorDetail"}}}},"request_id":{"type":"string"}}},"ErrorDetail":{"type":"object","required":["field","issue"],"additionalProperties":false,"properties":{"field":{"type":"string","description":"Dotted path to the offending field."},"issue":{"type":"string"}}},"Timestamp":{"type":"string","format":"date-time","description":"An RFC 3339 UTC timestamp with milliseconds.","examples":["2026-08-31T01:58:35.000Z"]},"Page":{"type":"object","description":"The envelope every collection uses. `data` carries the resource.","required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"Meta":{"type":"object","required":["api_version","documentation_url","openapi_url","server_time"],"additionalProperties":false,"properties":{"api_version":{"type":"string","examples":["v1"]},"documentation_url":{"type":"string","format":"uri"},"openapi_url":{"type":"string","format":"uri"},"server_time":{"type":"string","format":"date-time","description":"Current UTC time, in the format all timestamps use."}}},"Wedding":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^wed_.+$"},"slug":{"type":"string"},"partner_1_name":{"type":"string"},"partner_2_name":{"type":"string"},"couple_display_name":{"type":["string","null"]},"wedding_date":{"type":["string","null"],"format":"date","description":"A calendar day the couple owns in the venue's zone, with no instant behind it. It is the same day for every reader."},"wedding_end_date":{"type":["string","null"],"format":"date","description":"A calendar day the couple owns in the venue's zone, with no instant behind it. It is the same day for every reader."},"timezone":{"type":["string","null"],"description":"The IANA zone of the venue, such as `Europe/Rome`. Every instant this API returns is meant to be read in this zone. Null on a wedding with no venue yet, in which case instants were written against UTC."},"currency":{"type":"string"},"location":{"type":["string","null"]},"venue":{"type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"]},"place_id":{"type":["string","null"]},"latitude":{"type":["string","null"]},"longitude":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":["string","null"]}}},"room_selection_mode":{"type":"string"},"guest_pays_platform_fee":{"type":"boolean"},"room_payment_on_rsvp":{"type":"boolean","description":"When true, a guest's yes on the couple's Aisle site waits for the first payment on their room. `PUT /v1/guests/{guest_id}/rsvp` does not apply this rule."},"public_registry_enabled":{"type":"boolean"},"published":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","slug","partner_1_name","partner_2_name","couple_display_name","wedding_date","wedding_end_date","timezone","currency","location","venue","room_selection_mode","guest_pays_platform_fee","room_payment_on_rsvp","public_registry_enabled","published","created_at","updated_at"]},"SiteDesign":{"type":"object","additionalProperties":false,"properties":{"primary":{"type":"string"},"accent":{"type":"string"},"font_heading":{"type":"string"},"font_body":{"type":"string"},"ground":{"type":"string"},"ink":{"type":"string"},"muted":{"type":"string"},"rule":{"type":"string"},"radius":{"type":"number"},"cover":{"type":"string"},"nav_mode":{"type":"string"},"paragraph_font":{"type":"string","enum":["heading","body"]},"spacing_scale":{"type":"number"},"text_scale":{"type":"number"},"hero_text_color":{"type":["string","null"]},"adjusted":{"type":"object","additionalProperties":false,"properties":{"ink":{"type":"boolean"},"muted":{"type":"boolean"},"primary":{"type":"boolean"}}},"spec":{"$ref":"#/components/schemas/SiteSpec","description":"The site's design spec: every token, layout, section setting and part style, and where its blocks draw. Present only where the design spec is on for the wedding; read-only. Values are the couple's choices, before the contrast floors the fields above report. Clients must ignore keys they do not recognise: settings, parts and values are added as the spec grows."}},"required":["primary","accent","font_heading","font_body","ground","ink","muted","rule","radius","cover","nav_mode","paragraph_font","spacing_scale","text_scale","hero_text_color","adjusted"]},"SiteChapter":{"type":"object","additionalProperties":false,"properties":{"key":{"type":"string"},"kind":{"type":"string","enum":["fixed","custom"]},"position":{"type":"integer"},"enabled":{"type":"boolean"},"content":{"type":"object","additionalProperties":true,"description":"Chapter settings in snake_case. On the dress chapter, show_gender_labels defaults to true; false hides For her / For him headings while retaining descriptions and mood boards. Chapter prose strings support selected-text links as [label](https://example.com/). This applies to standfirst, masthead.subhead, letter/stay/travel/custom body paragraphs, closing.note and guestbook.prompt, including their translations. Only HTTP(S) destinations without credentials, spaces or control characters are links; other markup stays literal text. Strings retain this notation in API reads and writes. Render text and validated links separately, never as raw HTML. For the travel chapter, photo_position is above-description (default) or below-description. Below places the optional photo after the standfirst and body paragraphs, before the airport list. Omit to keep the saved position; set null to restore the default. No photo means no image or extra spacing. For the masthead chapter, show_rsvp_button is an optional boolean, off when absent. True adds a cover link to RSVP on standard Aisle covers when the current viewer can access RSVP. Omit to preserve the setting; false or null turns it off. Read-only shared links and disabled RSVP never show it. Brief retains its existing RSVP link without adding a second button; custom HTML covers are unchanged."}},"required":["key","kind","position","enabled","content"]},"Site":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"published":{"type":"boolean"},"hero_image_url":{"type":["string","null"]},"design":{"$ref":"#/components/schemas/SiteDesign"},"chapters":{"type":"array","items":{"$ref":"#/components/schemas/SiteChapter"}}},"required":["slug","published","hero_image_url","design","chapters"]},"SiteWithCollections":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"published":{"type":"boolean"},"hero_image_url":{"type":["string","null"]},"design":{"$ref":"#/components/schemas/SiteDesign"},"chapters":{"type":"array","items":{"$ref":"#/components/schemas/SiteChapter"}},"collections":{"$ref":"#/components/schemas/SiteCollections","description":"Present only when `expand` was passed, carrying one entry per name it asked for."}},"required":["slug","published","hero_image_url","design","chapters"]},"SiteCollections":{"type":"object","additionalProperties":false,"properties":{"events":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"dress_codes":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DressCode"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"properties":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicProperty"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"rooms":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRoom"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"airports":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicAirport"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"recommendations":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRecommendation"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"faqs":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicFaq"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"registry_items":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRegistryItem"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"songs":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicSongRequest"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"predictions":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicPrediction"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"guestbook":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicGuestbookEntry"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]},"photos":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicPhoto"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]}}},"Event":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^evt_.+$"},"name":{"type":"string"},"type":{"type":"string","enum":["welcome_dinner","ceremony","reception","brunch","rehearsal","cocktail_hour","after_party","activity","other"]},"starts_at":{"type":"string","format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"ends_at":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"all_day":{"type":"boolean","description":"True for an all-day item, such as a travel day: it has a day and no time. `starts_at` is then the start of its first day in the wedding's `timezone` and `ends_at`, when set, the start of its last day; show the days, never midnight. On a write, any time sent with the days is dropped. Defaults to false."},"venue":{"type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"]},"address":{"type":["string","null"]},"latitude":{"type":["string","null"]},"longitude":{"type":["string","null"]}}},"description":{"type":["string","null"]},"images":{"type":"array","items":{"type":"string"}},"dress_code_id":{"type":["string","null"],"pattern":"^drc_.+$"},"meal_selection":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"deadline":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"options":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"dietary_tags":{"type":"array","items":{"type":"string"}}},"required":["id","name"]}}}},"ticket":{"type":"object","additionalProperties":false,"properties":{"required":{"type":"boolean"},"price":{"type":["string","null"]},"pay_later":{"type":"boolean","description":"When true, an attending reply is recorded before the ticket is paid and the ticket stays owed. When false, an attending reply to a ticketed event waits for a completed ticket payment."}}},"rsvp":{"type":"object","additionalProperties":false,"properties":{"asks_separately":{"type":"boolean"},"options":{"type":["array","null"],"items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"counts_as":{"type":"string","enum":["attending","maybe","declined"]}},"required":["id","label","counts_as"]}}}},"visibility":{"type":"string","enum":["public","invite_only","internal"]},"audience_tags":{"type":"array","items":{"type":"string"}},"audience_property_ids":{"type":"array","items":{"type":"string","pattern":"^prp_.+$"}},"transport_note":{"type":["string","null"]},"transport_legs":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"location":{"type":"string"},"time":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"note":{"type":["string","null"]},"audience_tags":{"type":"array","items":{"type":"string"}},"audience_properties":{"type":"array","items":{"type":"string","pattern":"^prp_.+$"}},"audience_undecided":{"type":"boolean"}},"required":["id","location","time","note","audience_tags","audience_properties"]}},"sort_order":{"type":"integer"},"seating_not_required":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","type","starts_at","ends_at","all_day","venue","description","images","dress_code_id","meal_selection","ticket","rsvp","visibility","audience_tags","audience_property_ids","transport_note","transport_legs","sort_order","seating_not_required","created_at","updated_at"]},"EventInvitation":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^inv_.+$"},"guest_id":{"type":"string","pattern":"^gst_.+$"},"first_name":{"type":"string"},"last_name":{"type":"string"}},"required":["id","guest_id","first_name","last_name"]},"DressCode":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^drc_.+$"},"name":{"type":"string"},"description_ladies":{"type":["string","null"]},"pinterest_url_ladies":{"type":["string","null"]},"description_men":{"type":["string","null"]},"pinterest_url_men":{"type":["string","null"]},"inspiration_images":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","description_ladies","pinterest_url_ladies","description_men","pinterest_url_men","inspiration_images","created_at","updated_at"]},"PublishedSite":{"type":"object","additionalProperties":false,"properties":{"wedding":{"$ref":"#/components/schemas/Wedding"},"site":{"$ref":"#/components/schemas/Site"},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}},"required":["wedding","site","events"]},"Publication":{"type":"object","additionalProperties":false,"properties":{"published":{"type":"boolean"}},"required":["published"]},"ChapterOrder":{"type":"object","additionalProperties":false,"properties":{"order":{"type":"array","items":{"type":"string"}}},"required":["order"]},"SiteLanguages":{"type":"object","additionalProperties":false,"properties":{"default":{"type":"string","enum":["en","es","fr","it","de","pt","pl"]},"additional":{"type":"array","items":{"type":"string","enum":["en","es","fr","it","de","pt","pl"]},"maxItems":3}},"required":["default","additional"]},"SiteLanguagesPatch":{"type":"object","additionalProperties":false,"properties":{"default":{"type":"string","enum":["en","es","fr","it","de","pt","pl"]},"additional":{"type":"array","items":{"type":"string","enum":["en","es","fr","it","de","pt","pl"]},"maxItems":3}}},"SiteTranslations":{"type":"object","additionalProperties":{"type":"object"}},"DeletedResource":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"}},"required":["id"]},"GuestId":{"type":"string","pattern":"^gst_.+$"},"EventId":{"type":"string","pattern":"^evt_.+$"},"AccommodationId":{"type":"string","pattern":"^acc_.+$"},"PartyId":{"type":"string","pattern":"^pty_.+$"},"Room":{"type":"object","additionalProperties":false,"required":["id","property_id","name","type","description","capacity","capacity_max","bed_config","images","status","booking_url","booked_by_party_id","stay","rate","payment_schedule","created_at","updated_at"],"properties":{"id":{"$ref":"#/components/schemas/AccommodationId"},"property_id":{"type":["string","null"],"pattern":"^prp_.+$"},"name":{"type":"string"},"type":{"type":["string","null"]},"description":{"type":["string","null"]},"capacity":{"type":"integer"},"capacity_max":{"type":["integer","null"]},"bed_config":{"type":["string","null"]},"images":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"booking_url":{"type":["string","null"]},"booked_by_party_id":{"oneOf":[{"$ref":"#/components/schemas/PartyId"},{"type":"null"}]},"stay":{"type":"object","additionalProperties":false,"required":["check_in_date","check_out_date","check_in_time","check_out_time","check_in_notes"],"properties":{"check_in_date":{"type":["string","null"]},"check_out_date":{"type":["string","null"]},"check_in_time":{"type":["string","null"]},"check_out_time":{"type":["string","null"]},"check_in_notes":{"type":["string","null"]}}},"rate":{"type":"object","additionalProperties":false,"required":["requires_payment","unit","amount"],"properties":{"requires_payment":{"type":"boolean"},"unit":{"type":"string"},"amount":{"type":["string","null"]}}},"payment_schedule":{"type":"object","additionalProperties":false,"required":["deposit_unit","deposit_amount","deposit_due_date","balance_due_date"],"properties":{"deposit_unit":{"type":["string","null"]},"deposit_amount":{"type":["string","null"]},"deposit_due_date":{"type":["string","null"]},"balance_due_date":{"type":["string","null"]}}},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"GuestAddress":{"type":"object","additionalProperties":false,"required":["line1","line2","city","region","postal_code","country"],"properties":{"line1":{"type":["string","null"]},"line2":{"type":["string","null"]},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"postal_code":{"type":["string","null"]},"country":{"type":["string","null"]}}},"Guest":{"type":"object","additionalProperties":false,"required":["id","first_name","last_name","phone","phone_e164","phone_status","email","party_id","is_party_lead","plus_one_allowance","plus_one_for_guest_id","rsvp_status","rsvp_stage","rsvp_responded_at","rsvp_option_id","rsvp_option_label","rsvp_answers","dietary_restrictions","dietary_notes","accommodation_id","lodging_note","address","language","notes","tags","broadcast_channel","email_opted_out_at","sms_opted_out","whatsapp_opted_in_at","preferred_transport","preferred_transport_source","created_at","updated_at"],"properties":{"id":{"$ref":"#/components/schemas/GuestId"},"first_name":{"type":"string","minLength":1,"maxLength":120},"last_name":{"type":"string","maxLength":120},"phone":{"type":["string","null"]},"email":{"type":["string","null"],"format":"email"},"rsvp_status":{"type":"string","enum":["pending","attending","declined","maybe"]},"dietary_restrictions":{"type":["string","null"]},"dietary_notes":{"type":["string","null"]},"accommodation_id":{"oneOf":[{"$ref":"#/components/schemas/AccommodationId"},{"type":"null"}]},"lodging_note":{"type":["string","null"]},"notes":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"language":{"type":["string","null"]},"plus_one_allowance":{"type":"integer","minimum":0,"maximum":8},"is_party_lead":{"type":"boolean"},"phone_e164":{"type":["string","null"],"description":"Canonical E.164 identity with a leading +, or null when unresolved."},"phone_status":{"type":"string","enum":["valid","missing","invalid","unresolved"]},"party_id":{"oneOf":[{"$ref":"#/components/schemas/PartyId"},{"type":"null"}]},"plus_one_for_guest_id":{"oneOf":[{"$ref":"#/components/schemas/GuestId"},{"type":"null"}]},"rsvp_stage":{"type":["string","null"]},"rsvp_responded_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"rsvp_option_id":{"type":["string","null"]},"rsvp_option_label":{"type":["string","null"]},"rsvp_answers":{"type":"object","additionalProperties":true},"address":{"$ref":"#/components/schemas/GuestAddress"},"broadcast_channel":{"type":"string","enum":["email","sms","either"]},"email_opted_out_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"sms_opted_out":{"type":"boolean"},"whatsapp_opted_in_at":{"description":"Explicit recipient WhatsApp consent for the current canonical number, recorded from their own choice or inbound message. Cleared on phone identity change.","oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"preferred_transport":{"type":"string","enum":["sms","whatsapp"],"description":"Preferred transport. SMS delivery depends on provider country permissions. WhatsApp also requires recipient consent and an open service window or approved template."},"preferred_transport_source":{"type":["string","null"],"enum":["couple","guest","elena","api","system",null],"description":"Who chose the preference. Recipient WhatsApp consent is recorded separately in whatsapp_opted_in_at; an API preference change does not grant consent."},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"GuestCreate":{"type":"object","additionalProperties":false,"required":["first_name"],"properties":{"first_name":{"type":"string","minLength":1,"maxLength":120},"last_name":{"type":"string","maxLength":120},"phone":{"type":"string"},"phone_country":{"type":"string","enum":["AC","AD","AE","AF","AG","AI","AL","AM","AO","AR","AS","AT","AU","AW","AX","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BL","BM","BN","BO","BQ","BR","BS","BT","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CW","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","GA","GB","GD","GE","GF","GG","GH","GI","GL","GM","GN","GP","GQ","GR","GT","GU","GW","GY","HK","HN","HR","HT","HU","ID","IE","IL","IM","IN","IO","IQ","IR","IS","IT","JE","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","ME","MF","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PR","PS","PT","PW","PY","QA","RE","RO","RS","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","SS","ST","SV","SX","SY","SZ","TA","TC","TD","TG","TH","TJ","TK","TL","TM","TN","TO","TR","TT","TV","TW","TZ","UA","UG","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","XK","YE","YT","ZA","ZM","ZW"],"description":"Optional ISO country code for a national phone number. An explicit international calling code takes precedence."},"email":{"type":"string","format":"email"},"dietary_restrictions":{"type":"string"},"dietary_notes":{"type":"string"},"accommodation_id":{"oneOf":[{"$ref":"#/components/schemas/AccommodationId"},{"type":"null"}]},"lodging_note":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"language":{"type":"string"},"is_party_lead":{"type":"boolean"},"address":{"$ref":"#/components/schemas/GuestAddress"}}},"GuestPatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"first_name":{"type":"string","minLength":1,"maxLength":120},"last_name":{"type":"string","maxLength":120},"phone":{"type":["string","null"]},"phone_country":{"type":"string","enum":["AC","AD","AE","AF","AG","AI","AL","AM","AO","AR","AS","AT","AU","AW","AX","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BL","BM","BN","BO","BQ","BR","BS","BT","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CW","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","GA","GB","GD","GE","GF","GG","GH","GI","GL","GM","GN","GP","GQ","GR","GT","GU","GW","GY","HK","HN","HR","HT","HU","ID","IE","IL","IM","IN","IO","IQ","IR","IS","IT","JE","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","ME","MF","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PR","PS","PT","PW","PY","QA","RE","RO","RS","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","SS","ST","SV","SX","SY","SZ","TA","TC","TD","TG","TH","TJ","TK","TL","TM","TN","TO","TR","TT","TV","TW","TZ","UA","UG","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","XK","YE","YT","ZA","ZM","ZW"],"description":"Optional ISO country code for a national phone number. An explicit international calling code takes precedence."},"email":{"type":["string","null"],"format":"email"},"rsvp_status":{"type":"string","enum":["pending","attending","declined","maybe"]},"dietary_restrictions":{"type":["string","null"]},"dietary_notes":{"type":["string","null"]},"accommodation_id":{"oneOf":[{"$ref":"#/components/schemas/AccommodationId"},{"type":"null"}]},"lodging_note":{"type":["string","null"]},"notes":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"language":{"type":["string","null"]},"plus_one_allowance":{"type":"integer","minimum":0,"maximum":8},"is_party_lead":{"type":"boolean"},"party_with_guest_id":{"oneOf":[{"$ref":"#/components/schemas/GuestId"},{"type":"null"}]},"address_line_1":{"type":["string","null"]},"address_line_2":{"type":["string","null"]},"address_city":{"type":["string","null"]},"address_region":{"type":["string","null"]},"address_postal_code":{"type":["string","null"]},"address_country":{"type":["string","null"]},"broadcast_channel":{"type":["string","null"],"enum":["email","sms","either",null]},"preferred_transport":{"type":"string","enum":["sms","whatsapp"]}}},"GuestImportRow":{"type":"object","additionalProperties":false,"required":["first_name"],"properties":{"first_name":{"type":"string","minLength":1,"maxLength":120},"last_name":{"type":"string","maxLength":120},"phone":{"type":"string"},"phone_country":{"type":"string","enum":["AC","AD","AE","AF","AG","AI","AL","AM","AO","AR","AS","AT","AU","AW","AX","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BL","BM","BN","BO","BQ","BR","BS","BT","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CW","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","GA","GB","GD","GE","GF","GG","GH","GI","GL","GM","GN","GP","GQ","GR","GT","GU","GW","GY","HK","HN","HR","HT","HU","ID","IE","IL","IM","IN","IO","IQ","IR","IS","IT","JE","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","ME","MF","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PR","PS","PT","PW","PY","QA","RE","RO","RS","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","SS","ST","SV","SX","SY","SZ","TA","TC","TD","TG","TH","TJ","TK","TL","TM","TN","TO","TR","TT","TV","TW","TZ","UA","UG","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","XK","YE","YT","ZA","ZM","ZW"],"description":"Optional ISO country code for a national phone number. An explicit international calling code takes precedence."},"email":{"type":"string","format":"email"},"dietary_restrictions":{"type":"string"},"tags":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"string"}]},"language":{"type":"string"},"address":{"$ref":"#/components/schemas/GuestAddress"}}},"GuestImportResult":{"type":"object","additionalProperties":false,"required":["imported","skipped","errors","with_email","with_phone","with_address","with_language"],"properties":{"imported":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0},"errors":{"type":"array","items":{"type":"string"}},"with_email":{"type":"integer","minimum":0},"with_phone":{"type":"integer","minimum":0},"with_address":{"type":"integer","minimum":0},"with_language":{"type":"integer","minimum":0}}},"GuestBulkResult":{"type":"object","additionalProperties":false,"required":["ok","patched","total","results"],"properties":{"ok":{"type":"boolean"},"patched":{"type":"integer","minimum":0},"total":{"type":"integer","minimum":0},"guest_id":{"type":"string"},"error":{"type":"string"},"results":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["guest_id","status"],"properties":{"guest_id":{"$ref":"#/components/schemas/GuestId"},"status":{"type":"string","enum":["updated","failed","not_attempted"]},"error":{"type":"string"}}}}}},"GuestEventResponse":{"type":"object","additionalProperties":false,"required":["event_id","attending","option_id","option_label","meal_choice_id","meal_notes","updated_at"],"properties":{"event_id":{"$ref":"#/components/schemas/EventId"},"attending":{"type":["boolean","null"]},"option_id":{"type":["string","null"]},"option_label":{"type":["string","null"]},"meal_choice_id":{"type":["string","null"]},"meal_notes":{"type":["string","null"]},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"GuestRsvp":{"type":"object","additionalProperties":false,"required":["guest_id","status","stage","responded_at","option_id","option_label","answers","event_responses"],"properties":{"guest_id":{"$ref":"#/components/schemas/GuestId"},"status":{"type":"string","enum":["pending","attending","declined","maybe"]},"stage":{"type":["string","null"]},"responded_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"option_id":{"type":["string","null"]},"option_label":{"type":["string","null"]},"answers":{"type":"object","additionalProperties":true},"event_responses":{"type":"array","items":{"$ref":"#/components/schemas/GuestEventResponse"}}}},"GuestRsvpInput":{"type":"object","additionalProperties":false,"required":["status"],"properties":{"status":{"type":"string","enum":["attending","maybe","declined"]},"answers":{"type":"object","additionalProperties":true},"dietary_restrictions":{"type":["string","null"]},"dietary_notes":{"type":["string","null"]},"event_responses":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["event_id"],"properties":{"event_id":{"$ref":"#/components/schemas/EventId"},"attending":{"type":["boolean","null"]},"option_id":{"type":["string","null"]},"meal_choice_id":{"type":["string","null"]},"meal_notes":{"type":["string","null"]}}}}}},"GuestInvitation":{"type":"object","additionalProperties":false,"required":["event_id","invited"],"properties":{"event_id":{"$ref":"#/components/schemas/EventId"},"invited":{"type":"boolean"}}},"PersonalizedGuest":{"type":"object","additionalProperties":false,"required":["id","first_name","last_name","rsvp_status","rsvp_stage","rsvp_responded_at","dietary_restrictions","dietary_notes","accommodation_id","language"],"properties":{"id":{"$ref":"#/components/schemas/GuestId"},"first_name":{"type":"string"},"last_name":{"type":"string"},"rsvp_status":{"type":"string"},"rsvp_stage":{"type":["string","null"]},"rsvp_responded_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"dietary_restrictions":{"type":["string","null"]},"dietary_notes":{"type":["string","null"]},"accommodation_id":{"oneOf":[{"$ref":"#/components/schemas/AccommodationId"},{"type":"null"}]},"language":{"type":["string","null"]}}},"GuestTransportLeg":{"type":"object","additionalProperties":false,"required":["id","location","time","note"],"properties":{"id":{"type":"string"},"location":{"type":"string"},"time":{"type":["string","null"],"format":"date-time"},"note":{"type":["string","null"]}}},"PersonalizedEvent":{"type":"object","additionalProperties":false,"required":["id","name","type","starts_at","ends_at","all_day","venue","description","images","dress_code_id","meal_selection","ticket","rsvp","transport_note","transport_legs","sort_order","seating_not_required"],"properties":{"id":{"type":"string","pattern":"^evt_.+$"},"name":{"type":"string"},"type":{"type":"string","enum":["welcome_dinner","ceremony","reception","brunch","rehearsal","cocktail_hour","after_party","activity","other"]},"starts_at":{"type":"string","format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"ends_at":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"all_day":{"type":"boolean","description":"True for an all-day item, such as a travel day: it has a day and no time. `starts_at` is then the start of its first day in the wedding's `timezone` and `ends_at`, when set, the start of its last day; show the days, never midnight. On a write, any time sent with the days is dropped. Defaults to false."},"venue":{"type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"]},"address":{"type":["string","null"]},"latitude":{"type":["string","null"]},"longitude":{"type":["string","null"]}}},"description":{"type":["string","null"]},"images":{"type":"array","items":{"type":"string"}},"dress_code_id":{"type":["string","null"],"pattern":"^drc_.+$"},"meal_selection":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"deadline":{"type":["string","null"],"format":"date-time","description":"An instant, not a wall clock. Format it in the wedding's `timezone` from `GET /wedding`, never in the reader's zone."},"options":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"dietary_tags":{"type":"array","items":{"type":"string"}}},"required":["id","name"]}}}},"ticket":{"type":"object","additionalProperties":false,"properties":{"required":{"type":"boolean"},"price":{"type":["string","null"]},"pay_later":{"type":"boolean","description":"When true, an attending reply is recorded before the ticket is paid and the ticket stays owed. When false, an attending reply to a ticketed event waits for a completed ticket payment."}}},"rsvp":{"type":"object","additionalProperties":false,"properties":{"asks_separately":{"type":"boolean"},"options":{"type":["array","null"],"items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"counts_as":{"type":"string","enum":["attending","maybe","declined"]}},"required":["id","label","counts_as"]}}}},"transport_note":{"type":["string","null"]},"transport_legs":{"type":"array","items":{"$ref":"#/components/schemas/GuestTransportLeg"}},"sort_order":{"type":"integer"},"seating_not_required":{"type":"boolean"}}},"PersonalizedGuestSite":{"type":"object","additionalProperties":false,"required":["guest","site","events","rsvp","invitations","room"],"properties":{"guest":{"$ref":"#/components/schemas/PersonalizedGuest"},"site":{"$ref":"#/components/schemas/Site"},"events":{"type":"array","items":{"$ref":"#/components/schemas/PersonalizedEvent"}},"rsvp":{"$ref":"#/components/schemas/GuestRsvp"},"invitations":{"type":"array","items":{"$ref":"#/components/schemas/GuestInvitation"}},"room":{"oneOf":[{"$ref":"#/components/schemas/Room"},{"type":"null"}]}}},"Party":{"type":"object","additionalProperties":false,"required":["id","name","guest_ids","lead_guest_id","created_at","updated_at"],"properties":{"id":{"$ref":"#/components/schemas/PartyId"},"name":{"type":["string","null"],"maxLength":120},"guest_ids":{"type":"array","items":{"$ref":"#/components/schemas/GuestId"}},"lead_guest_id":{"oneOf":[{"$ref":"#/components/schemas/GuestId"},{"type":"null"}]},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"PartyCreate":{"type":"object","additionalProperties":false,"required":[],"properties":{"name":{"type":["string","null"],"maxLength":120},"guest_ids":{"type":"array","items":{"$ref":"#/components/schemas/GuestId"},"uniqueItems":true,"maxItems":200}}},"PartyPatch":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":["string","null"],"maxLength":120}}},"GuestAccessId":{"type":"string","pattern":"^gac_.+$"},"GuestAccess":{"type":"object","additionalProperties":false,"properties":{"id":{"$ref":"#/components/schemas/GuestAccessId"},"name":{"type":["string","null"],"maxLength":120},"guest_ids":{"type":"array","items":{"$ref":"#/components/schemas/GuestId"}},"expires_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"revoked_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","name","guest_ids","expires_at","revoked_at","created_at","updated_at"]},"GuestAccessCreate":{"type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"],"maxLength":120},"guest_ids":{"type":"array","items":{"$ref":"#/components/schemas/GuestId"},"minItems":1,"maxItems":200,"uniqueItems":true},"expires_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}],"description":"Future expiry instant, or null for no credential expiry."}},"required":["guest_ids"]},"GuestAccessPatch":{"type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"],"maxLength":120},"guest_ids":{"type":"array","items":{"$ref":"#/components/schemas/GuestId"},"minItems":1,"maxItems":200,"uniqueItems":true},"expires_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]}},"required":[],"minProperties":1},"GuestAccessIssued":{"type":"object","additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/GuestAccess"},"code":{"type":"string","description":"Generated invitation secret, returned only on creation or rotation. Save it securely; it cannot be read again."}},"required":["access","code"]},"GuestAccessVerify":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string","minLength":1,"maxLength":128}},"required":["code"]},"GuestAccessSessionVerify":{"type":"object","additionalProperties":false,"properties":{"session_token":{"type":"string","minLength":1,"maxLength":8192},"guest_id":{"$ref":"#/components/schemas/GuestId"}},"required":["session_token"]},"GuestAccessSessionIssued":{"type":"object","additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/GuestAccess"},"session_token":{"type":"string","description":"Guest access session for server-side verification. It cannot replace the wedding API key or a native Aisle guest cookie."},"expires_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["access","session_token","expires_at"]},"GuestAccessSession":{"type":"object","additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/GuestAccess"},"expires_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["access","expires_at"]},"PublicStay":{"type":"object","additionalProperties":false,"required":["check_in_date","check_out_date","check_in_time","check_out_time","check_in_notes"],"properties":{"check_in_date":{"oneOf":[{"type":"string","format":"date"},{"type":"null"}]},"check_out_date":{"oneOf":[{"type":"string","format":"date"},{"type":"null"}]},"check_in_time":{"oneOf":[{"type":"string"},{"type":"null"}]},"check_out_time":{"oneOf":[{"type":"string"},{"type":"null"}]},"check_in_notes":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"PublicRate":{"type":"object","additionalProperties":false,"required":["unit","amount"],"properties":{"unit":{"oneOf":[{"type":"string","enum":["room","night","party","head"]},{"type":"null"}]},"amount":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"PublicPaymentSchedule":{"type":"object","additionalProperties":false,"required":["deposit_unit","deposit_amount","deposit_due_date","balance_due_date"],"properties":{"deposit_unit":{"oneOf":[{"type":"string","enum":["percent","amount"]},{"type":"null"}]},"deposit_amount":{"oneOf":[{"type":"string"},{"type":"null"}]},"deposit_due_date":{"oneOf":[{"type":"string","format":"date"},{"type":"null"}]},"balance_due_date":{"oneOf":[{"type":"string","format":"date"},{"type":"null"}]}}},"PublicProperty":{"type":"object","additionalProperties":false,"required":["id","name","arrangement","room_selection_mode","effective_room_selection_mode","default_stay","rate","payment_schedule","block","address","place_id","latitude","longitude","description","images","booking_url","audience_tags","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^prp_.+$"},"name":{"type":"string"},"arrangement":{"type":"string","enum":["hosted_rooms","room_block","recommended","self_arranged"]},"room_selection_mode":{"oneOf":[{"type":"string","enum":["couple_assigned","guest_choice"]},{"type":"null"}],"description":"Stored property override. Null inherits the legacy wedding mode."},"effective_room_selection_mode":{"type":"string","enum":["couple_assigned","guest_choice"],"description":"Property override, then legacy wedding mode, then couple_assigned."},"address":{"oneOf":[{"type":"string"},{"type":"null"}]},"place_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"latitude":{"oneOf":[{"type":"string"},{"type":"null"}]},"longitude":{"oneOf":[{"type":"string"},{"type":"null"}]},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"images":{"type":"array","items":{"type":"string","format":"uri","pattern":"^https://"},"maxItems":6,"description":"Ordered hotel photo URLs. An empty list means no hotel photos; room photos are separate."},"booking_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"audience_tags":{"type":"array","items":{"type":"string"}},"default_stay":{"$ref":"#/components/schemas/PublicStay"},"rate":{"$ref":"#/components/schemas/PublicRate"},"payment_schedule":{"$ref":"#/components/schemas/PublicPaymentSchedule"},"block":{"type":"object","required":["rooms_held","booking_deadline","code"],"properties":{"rooms_held":{"oneOf":[{"type":"integer"},{"type":"null"}]},"booking_deadline":{"oneOf":[{"type":"string","format":"date"},{"type":"null"}]},"code":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicRoom":{"type":"object","additionalProperties":false,"required":["id","property_id","name","type","description","capacity","capacity_max","bed_config","images","status","booking_url","booked_by_party_id","stay","rate","payment_schedule","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^acc_.+$"},"property_id":{"oneOf":[{"type":"string","pattern":"^prp_.+$"},{"type":"null"}]},"name":{"type":"string"},"type":{"oneOf":[{"type":"string"},{"type":"null"}]},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"capacity":{"type":"integer"},"capacity_max":{"oneOf":[{"type":"integer"},{"type":"null"}]},"bed_config":{"oneOf":[{"type":"string"},{"type":"null"}]},"images":{"type":"array","items":{"type":"string","format":"uri"}},"status":{"type":"string","enum":["available","unavailable"]},"booking_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"booked_by_party_id":{"oneOf":[{"type":"string","pattern":"^pty_.+$"},{"type":"null"}]},"stay":{"$ref":"#/components/schemas/PublicStay"},"rate":{"type":"object","additionalProperties":false,"required":["requires_payment","unit","amount"],"properties":{"requires_payment":{"type":"boolean"},"unit":{"type":"string","enum":["room","night","party","head"]},"amount":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"payment_schedule":{"$ref":"#/components/schemas/PublicPaymentSchedule"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicAirport":{"type":"object","additionalProperties":false,"required":["id","name","code","country","description","travel_time_to_venue","sort_order","created_at"],"properties":{"id":{"type":"string","pattern":"^air_.+$"},"name":{"type":"string"},"code":{"type":"string"},"country":{"oneOf":[{"type":"string"},{"type":"null"}]},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"travel_time_to_venue":{"oneOf":[{"type":"string"},{"type":"null"}]},"sort_order":{"type":"integer"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicTransportOption":{"type":"object","additionalProperties":false,"required":["id","airport_id","mode","name","description","estimated_cost","estimated_time","booking_url","notes","provided","sort_order","created_at"],"properties":{"id":{"type":"string","pattern":"^trn_.+$"},"airport_id":{"oneOf":[{"type":"string","pattern":"^air_.+$"},{"type":"null"}]},"mode":{"type":"string","enum":["shuttle","rental_car","train","taxi","walking"]},"name":{"type":"string"},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"estimated_cost":{"oneOf":[{"type":"string"},{"type":"null"}]},"estimated_time":{"oneOf":[{"type":"string"},{"type":"null"}]},"booking_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"notes":{"oneOf":[{"type":"string"},{"type":"null"}]},"provided":{"type":"boolean"},"sort_order":{"type":"integer"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicRecommendation":{"type":"object","additionalProperties":false,"required":["id","name","description","details_html","emoji","category","difficulty","external_url","latitude","longitude","place_id","audience_tags","sort_order","created_at"],"properties":{"id":{"type":"string","pattern":"^rec_.+$"},"name":{"type":"string"},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"details_html":{"oneOf":[{"type":"string"},{"type":"null"}]},"emoji":{"oneOf":[{"type":"string"},{"type":"null"}]},"category":{"type":"string","enum":["hotel","food","activity","sight"],"description":"Responses may contain legacy hotel rows. New lodging belongs in properties and rooms; write requests cannot target hotel."},"difficulty":{"oneOf":[{"type":"string","enum":["easy","moderate","challenging"]},{"type":"null"}],"description":"Non-null only for activity or sight recommendations."},"external_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"latitude":{"oneOf":[{"type":"string"},{"type":"null"}]},"longitude":{"oneOf":[{"type":"string"},{"type":"null"}]},"place_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"audience_tags":{"type":"array","items":{"type":"string"}},"sort_order":{"type":"integer"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicFaq":{"type":"object","additionalProperties":false,"required":["id","question","answer","emoji","sort_order","created_at"],"properties":{"id":{"type":"string","pattern":"^faq_.+$"},"question":{"type":"string"},"answer":{"type":"string"},"emoji":{"oneOf":[{"type":"string"},{"type":"null"}]},"sort_order":{"type":"integer"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicRegistryItem":{"type":"object","additionalProperties":false,"required":["id","title","description","image_url","goal_amount","received_amount","gift_count","unit_label","unit_price","unit_count","allow_custom_amount","sort_order","active","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^reg_.+$"},"title":{"type":"string"},"description":{"oneOf":[{"type":"string"},{"type":"null"}]},"image_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"goal_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"received_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"gift_count":{"type":"integer"},"unit_label":{"oneOf":[{"type":"string"},{"type":"null"}]},"unit_price":{"oneOf":[{"type":"string"},{"type":"null"}]},"unit_count":{"oneOf":[{"type":"integer"},{"type":"null"}]},"allow_custom_amount":{"type":"boolean"},"sort_order":{"type":"integer"},"active":{"type":"boolean"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicRegistryContribution":{"type":"object","additionalProperties":false,"required":["id","registry_item_id","guest_id","amount","currency","message","anonymous","contributor_name","created_at"],"properties":{"id":{"type":"string","pattern":"^pay_.+$"},"registry_item_id":{"oneOf":[{"type":"string","pattern":"^reg_.+$"},{"type":"null"}]},"guest_id":{"oneOf":[{"type":"string","pattern":"^gst_.+$"},{"type":"null"}]},"amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"currency":{"type":"string"},"message":{"oneOf":[{"type":"string"},{"type":"null"}]},"anonymous":{"type":"boolean"},"contributor_name":{"oneOf":[{"type":"string"},{"type":"null"}]},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicRegistrySummary":{"type":"object","additionalProperties":false,"required":["goal_amount","received_amount","gift_count","unattributed_amount","unattributed_gift_count"],"properties":{"goal_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"received_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"gift_count":{"type":"integer"},"unattributed_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"unattributed_gift_count":{"type":"integer"}}},"PublicPhoto":{"type":"object","additionalProperties":false,"required":["id","url","width","height","section","captured_at","sort_index","created_at"],"properties":{"id":{"type":"string","pattern":"^pho_.+$"},"url":{"type":"string","format":"uri"},"width":{"type":"integer"},"height":{"type":"integer"},"section":{"type":"string"},"captured_at":{"oneOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"sort_index":{"type":"integer"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicCover":{"type":"object","additionalProperties":false,"required":["url","updated_at"],"properties":{"url":{"oneOf":[{"type":"string"},{"type":"null"}]},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicPhotoRegistration":{"type":"object","additionalProperties":false,"required":["added","skipped","photos"],"properties":{"added":{"type":"integer"},"skipped":{"type":"integer"},"photos":{"type":"array","items":{"$ref":"#/components/schemas/PublicPhoto"}}}},"PublicGuestbookEntry":{"type":"object","additionalProperties":false,"required":["id","guest_id","message","approved","created_at"],"properties":{"id":{"type":"string","pattern":"^gbk_.+$"},"guest_id":{"type":"string","pattern":"^gst_.+$"},"message":{"type":"string"},"approved":{"type":"boolean"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicSongRequest":{"type":"object","additionalProperties":false,"required":["id","guest_id","title","artist","spotify_track_id","album_art_url","preview_url","vote_count","created_at"],"properties":{"id":{"type":"string","pattern":"^sng_.+$"},"guest_id":{"type":"string","pattern":"^gst_.+$"},"title":{"type":"string"},"artist":{"oneOf":[{"type":"string"},{"type":"null"}]},"spotify_track_id":{"oneOf":[{"type":"string"},{"type":"null"}]},"album_art_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"preview_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"vote_count":{"type":"integer"},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicPrediction":{"type":"object","additionalProperties":false,"required":["id","question","options","active","sort_order","total_responses","option_counts","created_at"],"properties":{"id":{"type":"string","pattern":"^prd_.+$"},"question":{"type":"string"},"options":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","label"],"properties":{"id":{"type":"string"},"label":{"type":"string"}}}},"active":{"type":"boolean"},"sort_order":{"type":"integer"},"total_responses":{"type":"integer"},"option_counts":{"type":"object","additionalProperties":{"type":"integer"}},"created_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicPredictionResponse":{"type":"object","additionalProperties":false,"required":["id","prediction_id","guest_id","selected_option_id","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^prs_.+$"},"prediction_id":{"type":"string","pattern":"^prd_.+$"},"guest_id":{"type":"string","pattern":"^gst_.+$"},"selected_option_id":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}}},"PublicWeddingStats":{"type":"object","description":"Guest counts use the canonical headcount model. Event response counts are explicit guest-event replies. Room money uses settlement groups and completed, unrefunded accommodation payments. Registry totals use completed, unrefunded contribution payments and never registry_items.current_amount.","additionalProperties":false,"required":["guests","events","rooms","registry","content"],"properties":{"guests":{"type":"object","additionalProperties":false,"required":["invited","attending","declined","maybe","pending","replied","awaiting_reply","response_rate_percent"],"properties":{"invited":{"type":"integer"},"attending":{"type":"integer"},"declined":{"type":"integer"},"maybe":{"type":"integer"},"pending":{"type":"integer"},"replied":{"type":"integer"},"response_rate_percent":{"type":"integer"},"awaiting_reply":{"type":"integer","description":"Guests whose wedding RSVP is pending, null, unknown, or maybe."}}},"events":{"type":"object","additionalProperties":false,"required":["total","responses","attending_responses","declined_responses","awaiting_responses"],"properties":{"total":{"type":"integer"},"responses":{"type":"integer"},"attending_responses":{"type":"integer"},"declined_responses":{"type":"integer"},"awaiting_responses":{"type":"integer","description":"Stored guest-event response rows whose attending value is null."}}},"rooms":{"type":"object","additionalProperties":false,"required":["total","occupied","settlement_groups","settled_groups","priced_groups","total_amount","received_amount","outstanding_amount"],"properties":{"total":{"type":"integer"},"occupied":{"type":"integer","description":"Distinct non-null room IDs assigned to guests."},"settlement_groups":{"type":"integer"},"settled_groups":{"type":"integer"},"priced_groups":{"type":"integer"},"total_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"received_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."},"outstanding_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"A decimal currency amount. It is serialized as a string."}}},"registry":{"type":"object","additionalProperties":false,"required":["items","goal_amount","received_amount","gift_count"],"properties":{"items":{"type":"integer","description":"All registry items, including items hidden from guests."},"goal_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"The sum of goal amounts across all registry items, including hidden items."},"received_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{1,2})?$","description":"Completed, unrefunded registry contributions, including contributions to hidden items and unattributed contributions."},"gift_count":{"type":"integer","description":"Completed, unrefunded registry contributions, including contributions to hidden items and unattributed contributions."}}},"content":{"type":"object","additionalProperties":false,"required":["recommendations","faqs","song_requests","guestbook_entries","approved_guestbook_entries","predictions","prediction_responses"],"properties":{"recommendations":{"type":"integer","description":"All stored recommendation rows."},"faqs":{"type":"integer","description":"All stored FAQ rows."},"song_requests":{"type":"integer","description":"All stored song request rows."},"guestbook_entries":{"type":"integer","description":"All guestbook entries, including unapproved entries."},"approved_guestbook_entries":{"type":"integer","description":"Guestbook entries whose approved value is true."},"predictions":{"type":"integer","description":"All predictions, including inactive predictions."},"prediction_responses":{"type":"integer","description":"Responses across active and inactive predictions."}}}}},"PublicUploadInstructions":{"type":"object","description":"Return clientToken from your same-origin server proxy to @vercel/blob/client. The proxy, never browser JavaScript, adds the Aisle bearer API key when forwarding the token request. Register the uploaded URL with POST /photos or PATCH /site/cover.","additionalProperties":false,"required":["type","clientToken"],"properties":{"type":{"const":"blob.generate-client-token"},"clientToken":{"type":"string"}},"example":{"type":"blob.generate-client-token","clientToken":"vercel_blob_client_token"}},"PublicDeleted":{"type":"object","required":["deleted","id"],"properties":{"deleted":{"const":true},"id":{"type":"string","pattern":"^[a-z]{3}_.+$"}}},"PropertyResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicProperty"}}},"PropertyList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicProperty"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"RoomResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicRoom"}}},"RoomList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRoom"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"AirportResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicAirport"}}},"AirportList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicAirport"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"TransportOptionResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicTransportOption"}}},"TransportOptionList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicTransportOption"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"RecommendationResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicRecommendation"}}},"RecommendationList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRecommendation"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"FaqResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicFaq"}}},"FaqList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicFaq"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"RegistryItemResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicRegistryItem"}}},"RegistryItemList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRegistryItem"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"RegistryContributionResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicRegistryContribution"}}},"RegistryContributionList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRegistryContribution"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"RegistrySummaryResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicRegistrySummary"}}},"RegistrySummaryList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicRegistrySummary"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"PhotoResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicPhoto"}}},"PhotoList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicPhoto"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"PhotoRegistrationResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicPhotoRegistration"}}},"PhotoRegistrationList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicPhotoRegistration"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"CoverResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicCover"}}},"CoverList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicCover"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"GuestbookEntryResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicGuestbookEntry"}}},"GuestbookEntryList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicGuestbookEntry"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"SongRequestResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicSongRequest"}}},"SongRequestList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicSongRequest"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"PredictionResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicPrediction"}}},"PredictionList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicPrediction"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"PredictionResponseResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicPredictionResponse"}}},"PredictionResponseList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicPredictionResponse"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"WeddingStatsResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicWeddingStats"}}},"WeddingStatsList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicWeddingStats"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"DeletedResult":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/PublicDeleted"}}},"DeletedList":{"type":"object","additionalProperties":false,"required":["data","has_more","next_cursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicDeleted"}},"has_more":{"type":"boolean"},"next_cursor":{"oneOf":[{"type":"string"},{"type":"null"}]}}},"Checkout":{"type":"object","additionalProperties":false,"properties":{"payment_id":{"type":"string","pattern":"^pay_.+$"},"client_secret":{"type":["string","null"],"description":"Pass it to Stripe Elements in the browser. Do not store it as ledger state."},"stripe_publishable_key":{"type":"string","pattern":"^pk_","description":"Aisle's Stripe publishable key, for loadStripe() in the browser. It is public, and it is the only key that confirms this client_secret."},"amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},"base_amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},"service_fee":{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},"currency":{"type":"string"},"instalment":{"oneOf":[{"type":"string","enum":["deposit","balance"]},{"type":"null"}]},"charge_total":{"oneOf":[{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},{"type":"null"}]},"share":{"type":"boolean"}},"required":["payment_id","client_secret","stripe_publishable_key","amount","base_amount","service_fee","currency","instalment","charge_total","share"]},"Payment":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^pay_.+$"},"guest_id":{"oneOf":[{"type":"string","pattern":"^gst_.+$"},{"type":"null"}]},"type":{"type":"string"},"amount":{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},"platform_fee":{"oneOf":[{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},{"type":"null"}]},"fee_paid_by_guest":{"type":"boolean"},"currency":{"type":"string"},"status":{"type":"string","enum":["pending","completed","failed","refunded"]},"description":{"type":["string","null"]},"instalment":{"type":["string","null"]},"charge_total":{"oneOf":[{"type":"string","pattern":"^\\d+(?:\\.\\d{2})$","description":"A decimal currency amount serialized as a string."},{"type":"null"}]},"registry_contribution_id":{"oneOf":[{"type":"string","pattern":"^rct_.+$"},{"type":"null"}]},"accommodation_id":{"oneOf":[{"type":"string","pattern":"^acc_.+$"},{"type":"null"}]},"event_id":{"oneOf":[{"type":"string","pattern":"^evt_.+$"},{"type":"null"}]},"refunded_at":{"oneOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"refund_reason":{"type":["string","null"]},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","guest_id","type","amount","platform_fee","fee_paid_by_guest","currency","status","description","instalment","charge_total","registry_contribution_id","accommodation_id","event_id","refunded_at","refund_reason","created_at","updated_at"]},"PayoutStatus":{"type":"object","additionalProperties":false,"properties":{"connected":{"type":"boolean"},"charges_enabled":{"type":"boolean"},"details_submitted":{"type":"boolean"},"payouts_enabled":{"type":"boolean"},"onboarding_complete":{"type":"boolean"}},"required":["connected","charges_enabled","details_submitted","payouts_enabled","onboarding_complete"]},"PayoutLink":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","format":"uri"},"type":{"type":"string","enum":["onboarding","dashboard"]}},"required":["url","type"]},"SiteSpec":{"type":"object","additionalProperties":false,"properties":{"version":{"type":"integer","enum":[1]},"preset":{"type":["string","null"],"description":"The template this look was last set from, or null."},"tokens":{"type":"object","additionalProperties":false,"properties":{"palette":{"type":"object","additionalProperties":false,"properties":{"primary":{"type":"string"},"accent":{"type":"string"},"ground":{"type":["string","null"],"description":"Null: the stylesheet default."},"ink":{"type":["string","null"]},"muted":{"type":["string","null"],"description":"Null: derived from ground and ink."},"rule":{"type":["string","null"]},"swatches":{"type":"object","additionalProperties":{"type":"string"},"description":"Up to five named colours, by the name the couple gave each."}},"required":["primary","accent","ground","ink","muted","rule","swatches"]},"type":{"type":"object","additionalProperties":false,"properties":{"heading":{"type":"string"},"body":{"type":"string"},"names":{"type":"string"},"paragraph":{"type":"string"},"scale":{"type":"number"},"heading_style":{"type":"string"},"open":{"type":"object","additionalProperties":false,"properties":{"heading":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"family":{"type":"string","description":"A Google Fonts family."},"axes":{"type":"object","additionalProperties":{"type":"number"},"description":"One value per variable axis, by tag (`wght`, `opsz`). Empty: the family defaults."}},"required":["family","axes"]},{"type":"null"}]},"body":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"family":{"type":"string","description":"A Google Fonts family."},"axes":{"type":"object","additionalProperties":{"type":"number"},"description":"One value per variable axis, by tag (`wght`, `opsz`). Empty: the family defaults."}},"required":["family","axes"]},{"type":"null"}]},"names":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"family":{"type":"string","description":"A Google Fonts family."},"axes":{"type":"object","additionalProperties":{"type":"number"},"description":"One value per variable axis, by tag (`wght`, `opsz`). Empty: the family defaults."}},"required":["family","axes"]},{"type":"null"}]}},"required":["heading","body","names"]}},"required":["heading","body","names","paragraph","scale","heading_style","open"]},"shape":{"type":"object","additionalProperties":false,"properties":{"radius":{"type":"number"},"motif":{"type":"string"}},"required":["radius","motif"]},"rhythm":{"type":"object","additionalProperties":false,"properties":{"spacing":{"type":"number"},"divider":{"type":"string"}},"required":["spacing","divider"]},"motion":{"type":"object","additionalProperties":false,"properties":{"reveal":{"type":"string"},"cover":{"type":"string"}},"required":["reveal","cover"]}},"required":["palette","type","shape","rhythm","motion"]},"page":{"type":"object","additionalProperties":false,"properties":{"frame":{"type":"string"},"surface":{"type":"string"},"nav":{"type":"object","additionalProperties":false,"properties":{"mode":{"type":"string"},"labels":{"type":"boolean"},"style":{"type":"string"},"cta":{"type":"string"}},"required":["mode","labels","style","cta"]}},"required":["frame","surface","nav"]},"sections":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/SiteSpecSection"},"description":"Each section by its chapter key (`masthead`, `around_town`)."},"layers":{"type":"object","additionalProperties":false,"properties":{"cover":{"type":["string","null"],"description":"The block drawn as the cover."},"backdrop":{"type":["string","null"],"description":"The block drawn behind the whole page."},"seams":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"after":{"type":"string","description":"The chapter key it follows."},"block":{"type":"string"}},"required":["after","block"]}},"sections":{"type":"object","additionalProperties":{"type":"string"},"description":"A section's block, by chapter key."}},"required":["cover","backdrop","seams","sections"]},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/SiteSpecBlock"}},"legacy_document":{"type":"boolean","description":"True while a whole-page design is live: guests are served that page, which reads none of this."}},"required":["version","preset","tokens","page","sections","layers","blocks","legacy_document"]},"SiteSpecSection":{"type":"object","additionalProperties":false,"properties":{"variant":{"type":["string","null"],"description":"The section's arrangement; null for a section with one."},"params":{"type":"object","additionalProperties":true,"description":"Its settings, every one present at its value: `band`, `drop_cap`, `day_heads` and so on. On masthead, where the title sits and how large the names are."},"parts":{"type":"object","additionalProperties":{"type":"object","additionalProperties":true},"description":"Allowed styles on the reply's and the room picker's named parts, null where the part draws itself. Colours are names: primary, accent, ground, ink, or a swatch."}},"required":["variant","params","parts"]},"SiteSpecBlock":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"scope":{"type":"string","enum":["section","cover","seam","backdrop"]},"tier":{"type":"string","enum":["markup","scripted"]},"author":{"type":"string","enum":["elena","couple","preset"]},"fallback":{"type":"string","description":"What draws in its place if it is removed or fails."},"reads":{"type":"array","items":{"type":"string"}},"islands":{"type":"array","items":{"type":"string"},"description":"Platform parts drawn inside it, such as rsvp."}},"required":["id","scope","tier","author","fallback","reads","islands"]}}}}