openapi: 3.1.0
info:
  title: TikTape API
  description: Machine-readable API contract for TikTape historical Hyperliquid OHLCV data.
  version: 0.1.0
  contact:
    name: TikTape
    url: https://tiktape.xyz
  license:
    name: Proprietary
    url: https://tiktape.xyz/terms-and-conditions
servers:
  - url: https://tiktape.xyz
    description: Production
security:
  - ApiKeyAuth: []
paths:
  /api/v1/ohlcv:
    get:
      operationId: getOHLCV
      summary: Get historical OHLCV candles
      description: Returns historical OHLCV candles for a Hyperliquid coin and interval.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: coin
          in: query
          required: true
          description: Hyperliquid coin identifier, such as BTC, ETH, spot identifiers like @1, or HIP-3 identifiers like cash:NVDA.
          schema:
            type: string
          examples:
            perp:
              value: BTC
            spot:
              value: "@1"
            hip3:
              value: cash:NVDA
        - name: interval
          in: query
          required: true
          description: Candle interval.
          schema:
            type: string
            enum: [1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M]
          example: 1h
        - name: startTime
          in: query
          required: false
          description: Inclusive start timestamp in Unix milliseconds. If provided without endTime, endTime is derived from limit and interval.
          schema:
            type: integer
            format: int64
            minimum: 0
          example: 1767139200000
        - name: endTime
          in: query
          required: false
          description: Exclusive end timestamp in Unix milliseconds. If provided without startTime, startTime is derived from limit and interval.
          schema:
            type: integer
            format: int64
            minimum: 0
          example: 1767225600000
        - name: limit
          in: query
          required: false
          description: Maximum number of candles to return. Defaults to 500.
          schema:
            type: integer
            minimum: 1
            maximum: 10000
            default: 500
          example: 24
        - name: X-Force-Refresh
          in: header
          required: false
          description: Set to true to bypass closed-window cache. Requires a system API key.
          schema:
            type: string
            enum: ["true"]
      responses:
        "200":
          description: OHLCV candles returned.
          headers:
            X-RateLimit-Limit:
              description: Per-minute request limit for the authenticated key.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Remaining requests in the current per-minute bucket.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OHLCVResponse"
              examples:
                success:
                  value:
                    data:
                      - [1767139200000, "42000.0", "42100.0", "41900.0", "42050.0", "123.456"]
                    coin: BTC
                    interval: 1h
                    count: 1
        "400":
          description: Invalid request parameters, such as missing coin, unsupported coin, invalid interval, invalid limit, or invalid time range.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                missingCoin:
                  value:
                    error: coin parameter is required
                invalidInterval:
                  value:
                    error: "invalid interval: 99x"
                invalidLimit:
                  value:
                    error: limit must be 1-10000
        "401":
          description: Missing, invalid, or suspended API key.
          content:
            text/plain:
              schema:
                type: string
              examples:
                invalidKey:
                  value: '{"error":"invalid or missing API key"}'
                suspendedKey:
                  value: '{"error":"API key suspended"}'
        "403":
          description: System-key-only header was used with a non-system API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error: X-Force-Refresh requires system API key
        "429":
          description: Per-minute rate limit exceeded.
          headers:
            Retry-After:
              description: Seconds to wait before retrying after per-minute rate limiting.
              schema:
                type: integer
          content:
            text/plain:
              schema:
                type: string
              examples:
                rateLimit:
                  value: '{"error":"rate limit exceeded"}'
        "500":
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error: internal server error
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key header validated by the TikTape server.
  schemas:
    OHLCVResponse:
      type: object
      required: [data, coin, interval, count]
      additionalProperties: false
      properties:
        data:
          type: array
          description: Candles in chronological order, trimmed to the requested time range and limit.
          items:
            $ref: "#/components/schemas/Candle"
        coin:
          type: string
          description: Normalized Hyperliquid coin identifier used for the request.
        interval:
          type: string
          description: Requested candle interval.
          enum: [1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M]
        count:
          type: integer
          description: Number of candle arrays returned in data.
          minimum: 0
        gaps:
          type: array
          description: Present when discontinuities are detected between adjacent candles.
          items:
            $ref: "#/components/schemas/Gap"
    Candle:
      type: array
      description: Candle tuple in the order [timestamp_ms, open, high, low, close, volume]. Price and volume fields are strings to preserve decimal precision.
      minItems: 6
      maxItems: 6
      prefixItems:
        - type: integer
          format: int64
          description: Candle timestamp in Unix milliseconds.
        - type: string
          description: Open price.
        - type: string
          description: High price.
        - type: string
          description: Low price.
        - type: string
          description: Close price.
        - type: string
          description: Volume.
    Gap:
      type: object
      required: [from, to]
      additionalProperties: false
      properties:
        from:
          type: integer
          format: int64
          description: Last candle timestamp before the gap, in Unix milliseconds.
        to:
          type: integer
          format: int64
          description: First candle timestamp after the gap, in Unix milliseconds.
    ErrorResponse:
      type: object
      required: [error]
      additionalProperties: false
      properties:
        error:
          type: string
          description: Error message.
