openapi: 3.1.0
info:
  title: CryptoBots Developer API
  version: 1.0.0
  description: Read-only, user-scoped access to CryptoBots account and trading data.
servers:
  - url: https://api.cryptobots.io/api/v1/developer
security:
  - bearerApiKey: []
paths:
  /account:
    get:
      summary: Get the API key owner's account
      operationId: getAccount
      responses:
        "200": { $ref: "#/components/responses/Success" }
        "401": { $ref: "#/components/responses/Unauthorized" }
        "403": { $ref: "#/components/responses/Forbidden" }
  /bots:
    get:
      summary: List the owner's bots
      operationId: listBots
      responses:
        "200":
          description: Public bot status list
          content:
            application/json:
              schema: { $ref: "#/components/schemas/BotListEnvelope" }
  /bots/{botId}:
    get:
      summary: Get an owned bot's public lifecycle status
      description: Returns no bot configuration, strategy parameters, provider identifiers, or exchange credentials.
      operationId: getBot
      parameters: [ { $ref: "#/components/parameters/BotId" } ]
      responses:
        "200":
          description: Public bot lifecycle status
          content:
            application/json:
              schema: { $ref: "#/components/schemas/BotEnvelope" }
        "404": { $ref: "#/components/responses/NotFound" }
  /bots/{botId}/deals:
    get:
      summary: Get allowlisted executed-deal data shown in the web UI
      description: Raw provider fields and bot strategy parameters are removed.
      operationId: getBotDeals
      parameters: [ { $ref: "#/components/parameters/BotId" } ]
      responses:
        "200": { $ref: "#/components/responses/Success" }
  /bots/{botId}/stats:
    get:
      summary: Get bot performance statistics
      operationId: getBotStats
      parameters: [ { $ref: "#/components/parameters/BotId" } ]
      responses:
        "200": { $ref: "#/components/responses/Success" }
  /bots/{botId}/profits:
    get:
      summary: Get daily bot profits
      operationId: getBotProfits
      parameters: [ { $ref: "#/components/parameters/BotId" } ]
      responses:
        "200": { $ref: "#/components/responses/Success" }
  /events:
    get:
      summary: List normalized trade events
      operationId: listTradeEvents
      parameters:
        - { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 30 } }
        - { name: cursor, in: query, schema: { type: string }, description: nextCursor from the previous response }
        - { name: botId, in: query, schema: { type: string } }
        - { name: category, in: query, schema: { type: string } }
        - { name: severity, in: query, schema: { type: string, enum: [info, success, warning, critical] } }
        - { name: strategy, in: query, schema: { type: string } }
        - { name: exchange, in: query, schema: { type: string } }
        - { name: pair, in: query, schema: { type: string } }
        - { name: from, in: query, schema: { type: string, format: date-time } }
        - { name: to, in: query, schema: { type: string, format: date-time } }
      responses:
        "200":
          description: Paginated events
          content:
            application/json:
              schema:
                type: object
                required: [success, data]
                properties:
                  success: { type: boolean, const: true }
                  data:
                    type: object
                    required: [items, nextCursor]
                    properties:
                      items: { type: array, items: { $ref: "#/components/schemas/TradeEvent" } }
                      nextCursor: { type: [string, "null"] }
  /events/{eventId}:
    get:
      summary: Get one normalized trade event
      operationId: getTradeEvent
      parameters:
        - { name: eventId, in: path, required: true, schema: { type: string } }
      responses:
        "200": { $ref: "#/components/responses/Success" }
        "404": { $ref: "#/components/responses/NotFound" }
components:
  securitySchemes:
    bearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: cbio_live
  parameters:
    BotId: { name: botId, in: path, required: true, schema: { type: string } }
  responses:
    Success:
      description: Successful response
      content:
        application/json:
          schema: { $ref: "#/components/schemas/SuccessEnvelope" }
    Unauthorized:
      description: Invalid, expired, or revoked API key
    Forbidden:
      description: API key lacks the required scope
    NotFound:
      description: The resource does not exist or is not owned by this account
  schemas:
    SuccessEnvelope:
      type: object
      required: [success, data]
      properties:
        success: { type: boolean, const: true }
        data: {}
    BotStatus:
      type: object
      additionalProperties: false
      required: [id, status]
      properties:
        id: { type: string, description: Opaque CBIO bot ID }
        status: { type: string, enum: [ACTIVE, INACTIVE] }
        activeSince: { type: [string, "null"], format: date-time }
        inactiveSince: { type: [string, "null"], format: date-time }
        createdAt: { type: string, format: date-time }
        updatedAt: { type: string, format: date-time }
    BotEnvelope:
      type: object
      additionalProperties: false
      required: [success, data]
      properties:
        success: { type: boolean, const: true }
        data: { $ref: "#/components/schemas/BotStatus" }
    BotListEnvelope:
      type: object
      additionalProperties: false
      required: [success, data]
      properties:
        success: { type: boolean, const: true }
        data:
          type: array
          items: { $ref: "#/components/schemas/BotStatus" }
    TradeEvent:
      type: object
      required: [id, botId, type, category, severity, occurredAt]
      properties:
        id: { type: string }
        botId: { type: string }
        type: { type: string }
        category: { type: string }
        severity: { type: string, enum: [info, success, warning, critical] }
        strategy: { type: [string, "null"] }
        exchange: { type: [string, "null"] }
        pair: { type: [string, "null"] }
        direction: { type: [string, "null"] }
        realizedUsdProfit: { type: [number, "null"] }
        profitPercentage: { type: [number, "null"] }
        occurredAt: { type: string, format: date-time }
