openapi: 3.0.3
info:
  title: NearbyAssist Integrations API
  version: 1.0.0
  description: |
    Public integration surface for scheduling, OAuth account linking, and outbound webhook subscriptions.
servers:
  - url: https://www.nearbyassist.com
    description: Production
  - url: http://localhost:3000
    description: Local app
security:
  - bearerAuth: []
paths:
  /api/integrations/business/{businessId}/api-keys:
    post:
      summary: Create integration API key
      tags: [Business Integrations]
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: businessId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [label, scopes]
              properties:
                label:
                  type: string
                scopes:
                  type: array
                  items:
                    type: string
      responses:
        '201':
          description: Key created
        '401':
          description: Unauthorized
        '403':
          description: Forbidden

  /api/integrations/partner/me:
    get:
      summary: Validate integration key and return scope context
      tags: [Partner API]
      security:
        - integrationApiKey: []
      responses:
        '200':
          description: Partner context
        '401':
          description: Unauthorized

  /api/integrations/partner/availability:
    get:
      summary: Get availability slots
      tags: [Partner API]
      security:
        - integrationApiKey: []
      parameters:
        - in: query
          name: date_from
          required: true
          schema:
            type: string
            format: date-time
        - in: query
          name: date_to
          required: true
          schema:
            type: string
            format: date-time
        - in: query
          name: service_id
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Slots returned

  /api/integrations/partner/slot-holds:
    post:
      summary: Create temporary slot hold
      tags: [Partner API]
      security:
        - integrationApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [customer_user_id, starts_at, ends_at]
              properties:
                customer_user_id:
                  type: string
                  format: uuid
                starts_at:
                  type: string
                  format: date-time
                ends_at:
                  type: string
                  format: date-time
                ttl_minutes:
                  type: integer
                  default: 10
      responses:
        '201':
          description: Slot hold created
        '409':
          description: Slot conflict

  /api/integrations/partner/bookings:
    post:
      summary: Create booking using hold_token
      tags: [Partner API]
      security:
        - integrationApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [customer_user_id, start_time, end_time, hold_token]
              properties:
                customer_user_id:
                  type: string
                  format: uuid
                start_time:
                  type: string
                  format: date-time
                end_time:
                  type: string
                  format: date-time
                hold_token:
                  type: string
                notes:
                  type: string
      responses:
        '201':
          description: Booking created
        '409':
          description: Hold invalid or expired

  /api/integrations/partner/bookings/{bookingId}/status:
    put:
      summary: Update booking status
      tags: [Partner API]
      security:
        - integrationApiKey: []
      parameters:
        - in: path
          name: bookingId
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [status]
              properties:
                status:
                  type: string
                  enum: [pending_confirmation, confirmed, cancelled, completed]
      responses:
        '200':
          description: Status updated

  /api/integrations/partner/bookings/{bookingId}/reschedule:
    put:
      summary: Reschedule booking
      tags: [Partner API]
      security:
        - integrationApiKey: []
      parameters:
        - in: path
          name: bookingId
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [start_time, end_time]
              properties:
                start_time:
                  type: string
                  format: date-time
                end_time:
                  type: string
                  format: date-time
      responses:
        '200':
          description: Booking rescheduled

  /api/integrations/business/{businessId}/accounts:
    post:
      summary: Create provider integration account
      tags: [Business Integrations]
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: businessId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [provider, connection_type]
              properties:
                provider:
                  type: string
                  enum: [google_calendar, microsoft_365]
                connection_type:
                  type: string
                  enum: [oauth]
      responses:
        '201':
          description: Account created

  /api/integrations/business/{businessId}/accounts/{accountId}/oauth/start:
    post:
      summary: Start OAuth flow
      tags: [Business Integrations]
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: businessId
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: accountId
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [redirect_uri]
              properties:
                redirect_uri:
                  type: string
                  format: uri
      responses:
        '200':
          description: OAuth URL created

  /api/integrations/business/{businessId}/webhook-subscriptions:
    post:
      summary: Create outbound webhook subscription
      tags: [Business Integrations]
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: businessId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [provider, target_url, event_types]
              properties:
                provider:
                  type: string
                target_url:
                  type: string
                  format: uri
                event_types:
                  type: array
                  items:
                    type: string
      responses:
        '201':
          description: Subscription created

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    integrationApiKey:
      type: apiKey
      in: header
      name: X-Integration-Api-Key
