openapi: 3.1.0
info:
  title: SEMIPRO Cycling Intelligence
  version: 1.0.0
  description: >-
    First-party public contract for specialist cycling intelligence. The current
    released capability analyses cycling-event GPX routes. Public Activity
    Intelligence remains evaluation-only and is not represented as a callable endpoint.
  contact:
    name: SEMIPRO Support
    url: https://semipro.coach/support
  license:
    name: SEMIPRO Terms
    url: https://semipro.coach/legal/terms
externalDocs:
  description: Quickstart, sample GPX and recorded demonstration output
  url: https://semipro.coach/agents
servers:
  - url: https://api.semipro.coach
    description: Canonical public API
paths:
  /health:
    get:
      operationId: getSemiproIntelligenceHealth
      summary: Check the public SEMIPRO Cycling Intelligence service
      responses:
        '200':
          description: Service, contract and released-tool status
          content:
            application/json:
              schema:
                type: object
                required: [status, service, version, contract_version, transport, released_tools]
  /mcp:
    post:
      operationId: callSemiproIntelligenceMcp
      summary: Call the SEMIPRO Cycling Intelligence Streamable HTTP MCP server
      description: >-
        JSON-RPC 2.0 MCP endpoint. Discover the currently released tools with tools/list.
        Public MCP GPX inputs and derived results are processed transiently and are not retained.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/JsonRpcRequest'
                - type: array
                  minItems: 1
                  items:
                    $ref: '#/components/schemas/JsonRpcRequest'
      responses:
        '200':
          description: MCP JSON-RPC response
          content:
            application/json:
              schema: {}
        '202':
          description: MCP notification accepted
        '400':
          description: Invalid JSON-RPC request
  /v1/event-demands:
    get:
      operationId: getEventDemandCapability
      summary: Read Event Demand Intelligence capability metadata
      responses:
        '200':
          description: Current capability and contract metadata
          content:
            application/json:
              schema:
                type: object
    post:
      operationId: analyseEventDemand
      summary: Analyse the demands of a cycling-event GPX
      description: >-
        Returns route-derived terrain, decisive climbs, critical sections and bounded
        course judgement. It does not inspect an athlete, prescribe training, diagnose
        a medical issue or predict an outcome. Direct paid HTTP calls require a configured
        gateway receipt or provider credential; the public MCP has a rate-limited launch allowance.
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
            maxLength: 200
          description: Required for direct paid calls. A replay returns the original result.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EventDemandRequest'
      responses:
        '200':
          description: SEMIPRO Event Demand Intelligence result
          content:
            application/json:
              schema:
                type: object
                required: [object, contract_version, capability, route, judgement, uncertainty]
        '400':
          description: Invalid request
        '402':
          description: Payment or provider credential required
        '413':
          description: GPX exceeds the 3 MB limit
        '422':
          description: Invalid GPX
        '429':
          description: Rate limit reached
        '503':
          description: Analysis temporarily unavailable
components:
  schemas:
    JsonRpcRequest:
      type: object
      required: [jsonrpc, method]
      properties:
        jsonrpc:
          const: '2.0'
        id: {}
        method:
          type: string
        params:
          type: object
      additionalProperties: true
    EventDemandRequest:
      type: object
      properties:
        gpx_xml:
          type: string
          description: Complete GPX XML. Provide this or gpx_base64.
        gpx_base64:
          type: string
          contentEncoding: base64
          description: Base64-encoded GPX. Maximum decoded size is 3 MB.
        event:
          type: object
          additionalProperties: false
          properties:
            name:
              type: string
              maxLength: 160
            type:
              type: string
              enum: [road_race, criterium, time_trial, gran_fondo, sportive, gravel, mtb, mtb_xc, ultra, stage, triathlon_bike_leg, other]
            date:
              type: string
              format: date
            start_time:
              type: string
              pattern: '^([01]\d|2[0-3]):[0-5]\d$'
            course_format:
              type: string
              enum: [point_to_point, loop, laps]
            course_laps:
              type: integer
              minimum: 1
              maximum: 100
      anyOf:
        - required: [gpx_xml]
        - required: [gpx_base64]
      additionalProperties: false
