openapi: 3.0.3
info:
  title: TestMachine API
  description: API for accessing token data.
  version: 1.0.0
  contact:
    name: TestMachine
    url: https://testmachine.ai
servers:
  - url: https://api.testmachine.ai/v1
    description: Production API
tags:
  - name: Health
    description: Health check endpoints
  - name: Tokens
    description: Token information and behaviors
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authentication
  schemas:
    ServiceHealthStatus:
      type: object
      properties:
        name:
          type: string
        status:
          type: string
          enum:
            - healthy
            - unhealthy
            - unknown
        latencyMs:
          type: number
        error:
          type: string
      required:
        - name
        - status
    GatewayHealthStatus:
      type: object
      properties:
        status:
          type: string
          enum:
            - healthy
            - degraded
            - unhealthy
        timestamp:
          type: string
          format: date-time
        services:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              status:
                type: string
                enum:
                  - healthy
                  - unhealthy
                  - unknown
              latencyMs:
                type: number
              error:
                type: string
            required:
              - name
              - status
      required:
        - status
        - timestamp
        - services
    BehaviorSummary:
      type: object
      properties:
        kind:
          type: string
        function_signature:
          type: string
        authority_address:
          type: string
          nullable: true
        last_observed_at:
          type: string
          format: date-time
      required:
        - kind
        - function_signature
        - authority_address
        - last_observed_at
    ContractMetadata:
      type: object
      properties:
        is_verified:
          type: boolean
        deployer:
          type: string
          nullable: true
        contract_name:
          type: string
          nullable: true
      required:
        - is_verified
        - deployer
        - contract_name
    MarketData:
      type: object
      properties:
        price_usd:
          type: number
          nullable: true
        price_change_24h:
          type: number
          nullable: true
        volume_24h_usd:
          type: number
          nullable: true
        market_cap_usd:
          type: number
          nullable: true
      required:
        - price_usd
        - price_change_24h
        - volume_24h_usd
        - market_cap_usd
    TokenResponse:
      type: object
      properties:
        id:
          type: integer
        address:
          type: string
        network_id:
          type: integer
        name:
          type: string
          nullable: true
        symbol:
          type: string
          nullable: true
        last_analyzed:
          type: string
          nullable: true
          format: date-time
        behaviors:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              function_signature:
                type: string
              authority_address:
                type: string
                nullable: true
              last_observed_at:
                type: string
                format: date-time
            required:
              - kind
              - function_signature
              - authority_address
              - last_observed_at
        contract:
          type: object
          nullable: true
          properties:
            is_verified:
              type: boolean
            deployer:
              type: string
              nullable: true
            contract_name:
              type: string
              nullable: true
          required:
            - is_verified
            - deployer
            - contract_name
        market:
          type: object
          nullable: true
          properties:
            price_usd:
              type: number
              nullable: true
            price_change_24h:
              type: number
              nullable: true
            volume_24h_usd:
              type: number
              nullable: true
            market_cap_usd:
              type: number
              nullable: true
          required:
            - price_usd
            - price_change_24h
            - volume_24h_usd
            - market_cap_usd
      required:
        - id
        - address
        - network_id
        - name
        - symbol
        - last_analyzed
        - behaviors
        - contract
        - market
    CreateTokenRequest:
      type: object
      properties:
        address:
          type: string
          pattern: ^(0x)?[a-fA-F0-9]{40}$
        network_id:
          type: integer
        name:
          type: string
        symbol:
          type: string
      required:
        - address
        - network_id
    CreateTokenResponse:
      type: object
      properties:
        token_id:
          type: integer
      required:
        - token_id
    SubscribeTokenRequest:
      type: object
      properties:
        address:
          type: string
          pattern: ^(0x)?[a-fA-F0-9]{40}$
        network_id:
          type: integer
      required:
        - address
        - network_id
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
      required:
        - error
        - message
  parameters: {}
paths:
  /health:
    get:
      summary: Health Check
      description: Returns gateway health status and optionally backend service health.
      tags:
        - Health
      security: []
      parameters:
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: Include backend service health checks
          required: false
          description: Include backend service health checks
          name: services
          in: query
      responses:
        '200':
          description: Gateway is healthy or degraded
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - healthy
                      - degraded
                      - unhealthy
                  timestamp:
                    type: string
                    format: date-time
                  services:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        status:
                          type: string
                          enum:
                            - healthy
                            - unhealthy
                            - unknown
                        latencyMs:
                          type: number
                        error:
                          type: string
                      required:
                        - name
                        - status
                required:
                  - status
                  - timestamp
                  - services
        '503':
          description: Gateway is unhealthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - healthy
                      - degraded
                      - unhealthy
                  timestamp:
                    type: string
                    format: date-time
                  services:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        status:
                          type: string
                          enum:
                            - healthy
                            - unhealthy
                            - unknown
                        latencyMs:
                          type: number
                        error:
                          type: string
                      required:
                        - name
                        - status
                required:
                  - status
                  - timestamp
                  - services
  /tokens:
    post:
      summary: Create Token
      description: Register a new token for monitoring and analysis.
      tags:
        - Tokens
      security:
        - ApiKeyAuth: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                address:
                  type: string
                  pattern: ^(0x)?[a-fA-F0-9]{40}$
                network_id:
                  type: integer
                name:
                  type: string
                symbol:
                  type: string
              required:
                - address
                - network_id
      responses:
        '201':
          description: Token created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  token_id:
                    type: integer
                required:
                  - token_id
        '400':
          description: Bad request - invalid address or network
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '403':
          description: Forbidden - insufficient permissions
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '409':
          description: Conflict - token already exists
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '429':
          description: Rate limit exceeded
          headers:
            X-RateLimit-Limit:
              description: Request limit per window
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Remaining requests in current window
              schema:
                type: integer
            X-RateLimit-Reset:
              description: Unix timestamp when the rate limit resets
              schema:
                type: integer
            Retry-After:
              description: Seconds until rate limit resets
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
  /tokens/subscribe:
    post:
      summary: Subscribe to Token
      description: >-
        Subscribe to receive notifications for a token. The token must already
        exist.
      tags:
        - Tokens
      security:
        - ApiKeyAuth: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                address:
                  type: string
                  pattern: ^(0x)?[a-fA-F0-9]{40}$
                network_id:
                  type: integer
              required:
                - address
                - network_id
      responses:
        '200':
          description: Subscribed successfully
        '400':
          description: Bad request - invalid address or network
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '403':
          description: Forbidden - insufficient permissions
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '404':
          description: Token not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '429':
          description: Rate limit exceeded
          headers:
            X-RateLimit-Limit:
              description: Request limit per window
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Remaining requests in current window
              schema:
                type: integer
            X-RateLimit-Reset:
              description: Unix timestamp when the rate limit resets
              schema:
                type: integer
            Retry-After:
              description: Seconds until rate limit resets
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
  /tokens/{network}/{address}:
    get:
      summary: Get Token Details
      description: >-
        Returns aggregated token details including behaviors, contract metadata,
        and market data.
      tags:
        - Tokens
      security:
        - ApiKeyAuth: []
      parameters:
        - schema:
            type: string
            description: Network ID (e.g., 1 for Ethereum mainnet)
          required: true
          description: Network ID (e.g., 1 for Ethereum mainnet)
          name: network
          in: path
        - schema:
            type: string
            description: Token contract address
          required: true
          description: Token contract address
          name: address
          in: path
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: 'Include contract metadata (default: true)'
          required: false
          description: 'Include contract metadata (default: true)'
          name: contract
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: 'Include market/price data (default: true)'
          required: false
          description: 'Include market/price data (default: true)'
          name: price
          in: query
      responses:
        '200':
          description: Token details
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  address:
                    type: string
                  network_id:
                    type: integer
                  name:
                    type: string
                    nullable: true
                  symbol:
                    type: string
                    nullable: true
                  last_analyzed:
                    type: string
                    nullable: true
                    format: date-time
                  behaviors:
                    type: array
                    items:
                      type: object
                      properties:
                        kind:
                          type: string
                        function_signature:
                          type: string
                        authority_address:
                          type: string
                          nullable: true
                        last_observed_at:
                          type: string
                          format: date-time
                      required:
                        - kind
                        - function_signature
                        - authority_address
                        - last_observed_at
                  contract:
                    type: object
                    nullable: true
                    properties:
                      is_verified:
                        type: boolean
                      deployer:
                        type: string
                        nullable: true
                      contract_name:
                        type: string
                        nullable: true
                    required:
                      - is_verified
                      - deployer
                      - contract_name
                  market:
                    type: object
                    nullable: true
                    properties:
                      price_usd:
                        type: number
                        nullable: true
                      price_change_24h:
                        type: number
                        nullable: true
                      volume_24h_usd:
                        type: number
                        nullable: true
                      market_cap_usd:
                        type: number
                        nullable: true
                    required:
                      - price_usd
                      - price_change_24h
                      - volume_24h_usd
                      - market_cap_usd
                required:
                  - id
                  - address
                  - network_id
                  - name
                  - symbol
                  - last_analyzed
                  - behaviors
                  - contract
                  - market
        '400':
          description: Bad request - invalid network or address
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '403':
          description: Forbidden - insufficient permissions
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '404':
          description: Token not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '429':
          description: Rate limit exceeded
          headers:
            X-RateLimit-Limit:
              description: Request limit per window
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Remaining requests in current window
              schema:
                type: integer
            X-RateLimit-Reset:
              description: Unix timestamp when the rate limit resets
              schema:
                type: integer
            Retry-After:
              description: Seconds until rate limit resets
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                required:
                  - error
                  - message
