asyncapi: 2.6.0
info:
  title: LapsHub Live API Telemetry
  version: 1.0.0-preview
  description: |
    **Preview specification — not deployed.** MQTT topics for session telemetry
    ingest and subscribe. Obtain connection credentials via the GraphQL
    control plane (see graphql-v1.graphql).

defaultContentType: application/json

servers:
  mqtt:
    url: mqtts://live-mqtt.lapshub.com:8883
    protocol: mqtt
    description: Planned IoT endpoint (not live — Preview)

channels:
  live/{orgId}/{carId}/session/{sessionId}/telemetry:
    description: Bidirectional telemetry channel for one session (ACL separates pub vs sub).
    parameters:
      orgId:
        description: Organization id
        schema:
          type: string
      carId:
        description: Car / vehicle id
        schema:
          type: string
      sessionId:
        description: Live session id
        schema:
          type: string
    publish:
      operationId: ingestTelemetry
      summary: Car or integrator publishes points
      message:
        $ref: '#/components/messages/TelemetryMessage'
    subscribe:
      operationId: watchTelemetry
      summary: Pit / series app receives points
      message:
        $ref: '#/components/messages/TelemetryMessage'

components:
  messages:
    TelemetryMessage:
      name: TelemetryMessage
      title: Telemetry point or small batch
      contentType: application/json
      payload:
        $ref: '#/components/schemas/TelemetryEnvelope'

  schemas:
    TelemetryEnvelope:
      type: object
      required: [v, points]
      properties:
        v:
          type: integer
          const: 1
          description: Schema version
        points:
          type: array
          minItems: 1
          maxItems: 50
          items:
            $ref: '#/components/schemas/TelemetryPoint'
    TelemetryPoint:
      type: object
      required: [ts]
      properties:
        ts:
          type: string
          format: date-time
        lat:
          type: number
          format: double
        lon:
          type: number
          format: double
        speedMps:
          type: number
          format: float
        headingDeg:
          type: number
          format: float
        channels:
          type: object
          additionalProperties:
            type: number
