Aisle Parties API

Named households whose members reply together. Codes and guest sessions are managed by your application.

Operations 6

GET /parties List parties #
POST /parties Create a party #
GET /parties/{party_id} Read a party #
PATCH /parties/{party_id} Rename a party #
PUT /parties/{party_id}/guests/{guest_id} Join a party #
DELETE /parties/{party_id}/guests/{guest_id} Leave a party #

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-parties-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-parties-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Aisle Parties 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: Parties
  description: Named households whose members reply together. Codes and guest sessions are managed by your application.
paths:
  /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'
components:
  schemas:
    ErrorDetail:
      type: object
      required:
      - field
      - issue
      additionalProperties: false
      properties:
        field:
          type: string
          description: Dotted path to the offending field.
        issue:
          type: string
    PartyPatch:
      type: object
      additionalProperties: false
      required:
      - name
      properties:
        name:
          type:
          - string
          - 'null'
          maxLength: 120
    PartyId:
      type: string
      pattern: ^pty_.+$
    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
    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
    GuestId:
      type: string
      pattern: ^gst_.+$
    Timestamp:
      type: string
      format: date-time
      description: An RFC 3339 UTC timestamp with milliseconds.
      examples:
      - '2026-08-31T01:58:35.000Z'
    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'
  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'
    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