Aisle Payments API

Create guest checkouts and read the wedding-scoped payment ledger.

Operations 3

POST /checkouts Create a guest checkout #
GET /payments List payments #
GET /payments/{payment_id} Get a payment #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/aisle-wedding:aisle-wedding-payments-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

aisle-wedding-payments-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Aisle Payments 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

    and hosting your own frontend. ## Authentication


    Every request carries a wedding-scoped API key as a bearer token:


    Authorization: Bearer


    A key is scoped to exactly one wedding, and every read and write it makes

    stays inside that wedding. **Keys are server-side credentials.** Call this

    API from your own backend and never ship a key in browser JavaScript, where

    anyone loading your site can read it and act as the couple. ## Requests and responses


    Bodies are JSON. A request that sends a body must send

    `Content-Type: application/json`. Object ids are opaque strings with a type prefix, such as `gst_1042`. Treat

    them as strings: their shape may change and only the prefix is contractual. ## Dates and times


    Two kinds of value, and mixing them up is the most expensive mistake an

    integration can make here, because the result is a plausible number rather

    than an error. **Scheduled wedding times** are instants: RFC 3339 in UTC, for example

    `2026-06-13T14:00:00.000Z`. Event `starts_at` and `ends_at`,

    meal-selection deadlines and transport-leg times are all instants. **Format them in the wedding''s `timezone` from `GET /wedding`, never in

    the reader''s zone.** That ceremony is 16:00 at a wedding in `Europe/Rome`,

    and a guest browsing from California must still be told 16:00. Rendered in

    the reader''s own zone it reads 07:00, and a brunch the morning after moves to

    the previous evening. Nothing in the response marks that as wrong, so it is

    worth getting right once in a shared formatter. **Record timestamps** are instants too, and the same RFC 3339 UTC shape:

    `created_at`, `updated_at` and `rsvp_responded_at` say when something

    happened. Which zone you show those in is your choice, because they are not

    part of the wedding''s schedule. **Wall-clock values** are a day or a time the couple owns at the venue, with

    no instant behind them, so they are carried as separate date and time fields:

    `wedding_date` and `wedding_end_date`, and stay `check_in_date` with

    `check_in_time`. These are the same for every reader and need no zone. `timezone` is null on a wedding with no venue yet. Instants written before

    a venue was chosen were anchored to UTC. ## Pagination


    Collections are cursor-paged. Pass `limit` (1 to 100, default

    25) and `cursor`. Each response carries `has_more` and

    `next_cursor`; keep passing `next_cursor` back until `has_more` is false. An out-of-range `limit` is rejected rather than clamped, so a page you asked

    for is either the page you get or an error. ## Filtering


    Filters are query parameters named for the field they filter. Repeat a

    parameter, or comma-separate it, to mean "any of these":

    `?status=confirmed&status=pending`. Two different filters narrow each other. Each collection declares the filters it accepts; a parameter an endpoint does

    not declare is rejected rather than ignored, so a misspelled filter is an

    error and never a full page that looks filtered. A filter''s `next_cursor` is

    bound to that filter, so keep passing the same query string while you page. ## Errors


    Failures carry a JSON body with a stable `error.code`, a human-readable

    `error.message`, and a `request_id`. Branch on the code, log the message,

    and quote the request id when asking us about a specific call. Field-level

    problems appear in `error.details`. A field we refuse is always a `422 validation_failed`, whether it arrived in

    the query string or in the request body, and every field at fault is listed in

    `error.details` rather than only the first. Each entry names the field in the

    spelling you sent, dotted through objects and indexed through lists, such as

    `options.1.id`. `error.message` is one sentence for the whole request and

    carries nothing you need to parse. A `400 invalid_request` means the request

    itself could not be read, such as a body that is not a JSON object. ## Rate limits


    Responses carry `X-RateLimit-Limit`,

    `X-RateLimit-Remaining` and `X-RateLimit-Reset`.'
  contact:
    name: Aisle
    url: https://aisle.wedding
servers:
- url: https://api.aisle.wedding/v1
  description: Production
security:
- bearerAuth: []
tags:
- name: Payments
  description: Create guest checkouts and read the wedding-scoped payment ledger.
paths:
  /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.


        Aisle owns admission, ticket, room, instalment, currency, status, and fee values. Only a registry contribution, and a gift towards a pay-what-you-want room, accept a caller-chosen amount. Accommodation checkouts use the same durable room hold, household share, and recovery rules as Aisle''s guest site.


        A 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.


        A 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.
                  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: 'Only for a pay-what-you-want room: the amount the guest chose to give, greater than 0 and no more than 10000. The room is held whether or not they give.'
                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'
components:
  schemas:
    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
    ErrorDetail:
      type: object
      required:
      - field
      - issue
      additionalProperties: false
      properties:
        field:
          type: string
          description: Dotted path to the offending field.
        issue:
          type: string
    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
    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
    Timestamp:
      type: string
      format: date-time
      description: An RFC 3339 UTC timestamp with milliseconds.
      examples:
      - '2026-08-31T01:58:35.000Z'
  responses:
    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'
    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'
    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'
    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'
    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'
    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'
    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'
    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'
    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'
    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'
    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'
  headers:
    Retry-After:
      description: Seconds to wait before retrying a rate-limited call.
      schema:
        type: integer
        minimum: 1
    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
    X-RateLimit-Limit:
      description: Requests permitted in the current window.
      schema:
        type: integer
    X-Aisle-Api-Version:
      description: The API version that served this request.
      schema:
        type: string
    X-Request-Id:
      description: Correlation id for this request. Quote it when reporting a problem.
      schema:
        type: string
  parameters:
    cursor:
      name: cursor
      in: query
      required: false
      description: The `next_cursor` from the previous page. Omit for the first page.
      schema:
        type: string
    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
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: A wedding-scoped API key. Send it from your own server; never from a browser.
externalDocs:
  url: https://api.aisle.wedding/docs
  description: API reference