Launch27 Customer Bookings API

Authenticated customer-portal booking CRUD.

OpenAPI Specification

launch27-customer-bookings-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Launch27 Account Customer Bookings API
  description: 'Unofficial-but-real, actively used REST API for Launch27, a booking and scheduling platform for cleaning service businesses. Documented in a public Bitbucket wiki (https://bitbucket.org/awoo23/api-2.0/wiki/Home) linked from the launch27.com site footer, rather than in Launch27''s first-party docs.launch27.com knowledge base. The API is multi-tenant: every client account has its own subdomain. This document models the current v2.1 surface (the deprecated v2.0 surface is not modeled). Not every endpoint mentioned in the wiki is represented here in full schema detail; refer to the wiki pages linked per operation for complete field-by-field documentation.'
  version: '2.1'
  contact:
    name: API Evangelist
    email: kin@apievangelist.com
servers:
- url: https://{tenant}.launch27.com/v1
  description: Production (per-tenant subdomain)
  variables:
    tenant:
      default: acme
      description: Launch27 client account subdomain.
- url: https://{tenant}.l27.co/v1
  description: Testing/sandbox (per-tenant subdomain)
  variables:
    tenant:
      default: acme-sandbox
      description: Launch27 sandbox account subdomain.
security:
- bearerAuth: []
tags:
- name: Customer Bookings
  description: Authenticated customer-portal booking CRUD.
paths:
  /customer/bookings:
    get:
      operationId: listCustomerBookings
      tags:
      - Customer Bookings
      summary: List active bookings for the logged-in customer
      parameters:
      - name: from
        in: query
        schema:
          type: string
          format: date
      - name: to
        in: query
        schema:
          type: string
          format: date
      - name: query
        in: query
        description: Free-text search across address, city, phone.
        schema:
          type: string
      - name: options
        in: query
        description: Comma-separated; completed, not_completed, with_feedback, without_feedback.
        schema:
          type: string
      - name: limit
        in: query
        schema:
          type: integer
      - name: offset
        in: query
        schema:
          type: integer
      - name: sort
        in: query
        schema:
          type: string
          enum:
          - asc
          - desc
          default: desc
      responses:
        '200':
          description: List of bookings.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Booking'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: User is not a customer user.
    post:
      operationId: createCustomerBooking
      tags:
      - Customer Bookings
      summary: Create a new booking as the logged-in customer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerBookingRequest'
      responses:
        '200':
          description: Booking created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingCreatedResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
  /customer/bookings/count:
    get:
      operationId: countCustomerBookings
      tags:
      - Customer Bookings
      summary: Count active bookings for the logged-in customer
      responses:
        '200':
          description: Booking count.
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: User is not a customer user.
  /customer/bookings/{id}:
    parameters:
    - name: id
      in: path
      required: true
      description: Booking unique ID.
      schema:
        type: integer
    get:
      operationId: getCustomerBooking
      tags:
      - Customer Bookings
      summary: Get a single booking's details
      responses:
        '200':
          description: Booking detail.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Customer has no access to booking.
    put:
      operationId: updateCustomerBooking
      tags:
      - Customer Bookings
      summary: Update or reschedule an existing booking
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCustomerBookingRequest'
      responses:
        '200':
          description: Updated booking.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Booking'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
  /customer/bookings/{id}/cancel:
    post:
      operationId: cancelCustomerBooking
      tags:
      - Customer Bookings
      summary: Cancel an existing booking
      parameters:
      - name: id
        in: path
        required: true
        description: Booking unique ID.
        schema:
          type: integer
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelBookingRequest'
      responses:
        '200':
          description: Booking cancelled.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
components:
  schemas:
    CustomerBookingRequest:
      type: object
      required:
      - address
      - frequency_id
      - service_date
      - arrival_window
      - services
      - payment_method
      properties:
        location_id:
          type: integer
          nullable: true
        original_booking_id:
          type: integer
          nullable: true
          description: '"Book This Again" reference to a prior booking owned by the customer.'
        address:
          type: string
        city:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        zip:
          type: string
          nullable: true
        phone:
          type: string
          nullable: true
        sms_notifications:
          type: boolean
          nullable: true
        frequency_id:
          type: integer
        service_date:
          type: string
        arrival_window:
          type: integer
        services:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/ServiceSelection'
        discount_code:
          type: string
          nullable: true
        tip:
          type: number
          nullable: true
        tip_recurring:
          type: boolean
          nullable: true
        payment_method:
          type: string
          enum:
          - stripe
          - paypal
          - cash
          - check
        customer_notes:
          type: string
          nullable: true
        custom_fields:
          type: array
          nullable: true
          items:
            type: object
            additionalProperties: true
    BookingCreatedResponse:
      type: object
      properties:
        id:
          type: integer
        ga_transaction:
          type: object
          additionalProperties: true
        ga_item:
          type: object
          additionalProperties: true
    ServiceSelection:
      type: object
      required:
      - id
      properties:
        id:
          type: integer
        hourly:
          type: object
          nullable: true
          properties:
            quantity:
              type: integer
            minutes:
              type: integer
        extras:
          type: array
          nullable: true
          items:
            type: object
            required:
            - id
            - quantity
            properties:
              id:
                type: integer
              quantity:
                type: integer
              recurring:
                type: boolean
                nullable: true
        pricing_parameters:
          type: array
          nullable: true
          items:
            type: object
            required:
            - id
            - quantity
            properties:
              id:
                type: integer
              quantity:
                type: integer
    UpdateCustomerBookingRequest:
      allOf:
      - $ref: '#/components/schemas/CustomerBookingRequest'
      - type: object
        properties:
          create_next_recurring:
            type: object
            nullable: true
            required:
            - service_date
            properties:
              service_date:
                type: string
    Booking:
      type: object
      description: See https://bitbucket.org/awoo23/api-2.0/wiki/Get_booking_for_customer for full attribute documentation.
      additionalProperties: true
      properties:
        id:
          type: integer
        digest:
          type: string
        service_date:
          type: string
          format: date-time
        arrival_window:
          type: integer
        address:
          type: object
          additionalProperties: true
        active:
          type: boolean
        completed:
          type: boolean
        name:
          type: string
        email:
          type: string
        phone:
          type: string
        frequency:
          type: object
          additionalProperties: true
        payment_method_info:
          type: object
          additionalProperties: true
        services:
          type: array
          items:
            type: object
            additionalProperties: true
        summary:
          type: object
          additionalProperties: true
        actions:
          type: object
          additionalProperties: true
    CancelBookingRequest:
      type: object
      properties:
        confirmed_late:
          type: boolean
        confirmed_fee:
          type: number
          nullable: true
        confirmed_recurring:
          type: object
          nullable: true
          properties:
            cancel_future:
              type: boolean
        reason:
          type: string
          nullable: true
  responses:
    Unauthorized:
      description: Missing/invalid Authorization header, or invalid credentials.
    ValidationError:
      description: JSON schema or data validation error.
      content:
        application/json:
          schema:
            type: object
            additionalProperties: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'JWT returned as `bearer` in the Login response. Sent as `Authorization: Bearer <JWT>`. A legacy `email:token` form (Authorization: email:token) existed but was retired March 1, 2023.'