openapi: 3.0.3
info:
  title: Smart Home Bot API
  version: 1.0.0
  description: >
    Secret-based REST API for bot integrations. The endpoint surface mirrors the MCP API
    except for OAuth routes. Each request must include the bot secret and the target user id.

servers:
  - url: /api/bot/v1

security:
  - botSecret: []
    botUserId: []

components:
  securitySchemes:
    botSecret:
      type: apiKey
      in: header
      name: Authorization
      description: Use `Bearer <bot_secret>`.
    botUserId:
      type: apiKey
      in: header
      name: X-Bot-User-Id
      description: Header name may be overridden by `BOT_API_USER_ID_HEADER`.

  schemas:
    ErrorResponse:
      type: object
      properties:
        message:
          type: string

    Me:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        email:
          type: string
          format: email
        allowedLocations:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              title:
                type: string
        scopes:
          type: array
          items:
            type: string

    MqttTokenResponse:
      type: object
      required: [token, locationId, expiresIn]
      properties:
        token:
          type: string
        locationId:
          type: string
          format: uuid
        expiresIn:
          type: integer
        expiresAt:
          type: string
          format: date-time

    Location:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        protected:
          type: boolean
        latitude:
          type: number
          nullable: true
        longitude:
          type: number
          nullable: true

    Room:
      type: object
      additionalProperties: true

    Device:
      type: object
      additionalProperties: true

    Scenario:
      type: object
      additionalProperties: true

    Schedule:
      type: object
      additionalProperties: true

    ScenarioRunResponse:
      type: object
      properties:
        runId:
          type: string
          format: uuid
        status:
          type: string

paths:
  /me:
    get:
      summary: Show user profile for bot context
      responses:
        '200':
          description: User profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Me'

  /token:
    get:
      summary: Issue short-lived MQTT token
      parameters:
        - in: query
          name: location_id
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: MQTT token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MqttTokenResponse'

  /locations:
    get:
      summary: List locations available to the target user
      responses:
        '200':
          description: Locations list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Location'

  /locations/{location}:
    get:
      summary: Show location details
      parameters:
        - in: path
          name: location
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Location details

  /locations/{location}/rooms:
    get:
      summary: List rooms for a location
      parameters:
        - in: path
          name: location
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Rooms list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Room'

  /rooms/{room}:
    get:
      summary: Show room details
      parameters:
        - in: path
          name: room
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Room details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Room'

  /locations/{location}/devices:
    get:
      summary: List devices by location
      parameters:
        - in: path
          name: location
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Devices list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Device'

  /rooms/{room}/devices:
    get:
      summary: List devices by room
      parameters:
        - in: path
          name: room
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Devices list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Device'

  /devices/{device}:
    get:
      summary: Show device details
      parameters:
        - in: path
          name: device
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Device details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'

  /scenes:
    get:
      summary: List scenes
      parameters:
        - in: query
          name: location_id
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Scenes list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Scenario'
    post:
      summary: Create scene
      responses:
        '201':
          description: Created scene
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Scenario'

  /scenes/{scene}:
    get:
      summary: Show scene
      parameters:
        - in: path
          name: scene
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Scene details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Scenario'
    put:
      summary: Update scene
      parameters:
        - in: path
          name: scene
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Updated scene
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Scenario'
    patch:
      summary: Patch scene
      parameters:
        - in: path
          name: scene
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Updated scene
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Scenario'
    delete:
      summary: Delete scene
      parameters:
        - in: path
          name: scene
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Scene deleted

  /scenes/{scene}/run:
    post:
      summary: Run scene
      parameters:
        - in: path
          name: scene
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Scene run accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScenarioRunResponse'

  /schedules:
    get:
      summary: List schedules
      parameters:
        - in: query
          name: location_id
          schema:
            type: string
            format: uuid
        - in: query
          name: active
          schema:
            type: boolean
        - in: query
          name: scenario_id
          schema:
            type: string
            format: uuid
        - in: query
          name: device_id
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Schedules list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Schedule'
    post:
      summary: Create schedule
      responses:
        '201':
          description: Created schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Schedule'

  /schedules/{schedule}:
    get:
      summary: Show schedule
      parameters:
        - in: path
          name: schedule
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Schedule details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Schedule'
    put:
      summary: Update schedule
      parameters:
        - in: path
          name: schedule
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Updated schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Schedule'
    patch:
      summary: Patch schedule
      parameters:
        - in: path
          name: schedule
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Updated schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Schedule'
    delete:
      summary: Delete schedule
      parameters:
        - in: path
          name: schedule
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Schedule deleted

  /schedules/{schedule}/toggle:
    post:
      summary: Toggle schedule active state
      parameters:
        - in: path
          name: schedule
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Updated schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Schedule'
