openapi: 3.0.3
info:
  title: OBPAI Tier List API
  version: 1.0.0
  description: |
    同步生成天梯图。使用官方模板或自定义条目，一次 POST 返回 imageUrl。
    在线文档：https://obpai.com/developers/docs
  contact:
    name: OBPAI
    url: https://obpai.com/developers
servers:
  - url: https://obpai.com
    description: Production
paths:
  /api/v1/render:
    get:
      summary: API 元信息
      operationId: renderMeta
      responses:
        '200':
          description: OK
    post:
      summary: 生成天梯图
      operationId: renderTierList
      security:
        - bearerAuth: []
        - apiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenderRequest'
            examples:
              custom:
                summary: 自定义模式
                value:
                  mode: custom
                  title: 我的技术栈
                  items:
                    - type: text
                      label: React
                    - type: text
                      label: Vue
                  tiers:
                    - title: S
                      items: [0]
                    - title: A
                      items: [1]
                  watermark: false
              template:
                summary: 官方模板
                value:
                  mode: template
                  templateId: 1786595042260
                  tiers:
                    - title: 夯
                      items: [item_0, item_1]
      responses:
        '200':
          description: 成图成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RenderResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /api/v1/templates:
    get:
      summary: 模板列表
      operationId: listTemplates
      security:
        - bearerAuth: []
        - apiKeyAuth: []
      parameters:
        - name: mode
          in: query
          schema:
            type: string
            enum: [recommended, hot, newest]
        - name: q
          in: query
          schema:
            type: string
        - name: categoryId
          in: query
          schema:
            type: integer
        - name: limit
          in: query
          schema:
            type: integer
            default: 24
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: locale
          in: query
          schema:
            type: string
            enum: [zh, en, ru]
      responses:
        '200':
          description: OK
  /api/v1/templates/{id}:
    get:
      summary: 模板详情
      operationId: getTemplate
      security:
        - bearerAuth: []
        - apiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            oneOf:
              - type: integer
              - type: string
                enum: [custom]
        - name: locale
          in: query
          schema:
            type: string
            enum: [zh, en, ru]
      responses:
        '200':
          description: OK
  /api/v1/keys:
    get:
      summary: 列出 API Keys（需登录）
      operationId: listKeys
      responses:
        '200':
          description: OK
    post:
      summary: 创建 API Key（需登录）
      operationId: createKey
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
      responses:
        '200':
          description: OK
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
  schemas:
    RenderRequest:
      type: object
      properties:
        mode:
          type: string
          enum: [template, custom, inline]
        templateId:
          type: integer
        title:
          type: string
        locale:
          type: string
          enum: [zh, en, ru]
        aspectRatio:
          type: string
          enum: ['3:4', '9:16', '1:1', '16:9']
        theme:
          type: string
          enum: [night, paper, arcade]
          description: Visual skin only. Does not change ranking content.
          default: night
        watermark:
          type: boolean
          default: true
        tracks:
          type: array
          items:
            type: object
            properties:
              title:
                type: string
              color:
                type: string
        items:
          type: array
          items:
            oneOf:
              - type: string
              - type: object
                properties:
                  type:
                    type: string
                    enum: [text, url]
                  label:
                    type: string
                  url:
                    type: string
        tiers:
          type: array
          items:
            type: object
            required: [title, items]
            properties:
              title:
                type: string
              items:
                type: array
                items:
                  oneOf:
                    - type: integer
                    - type: string
    RenderResponse:
      type: object
      properties:
        success:
          type: boolean
        renderId:
          type: string
        imageUrl:
          type: string
          format: uri
        imagePath:
          type: string
        width:
          type: integer
        height:
          type: integer
        aspectRatio:
          type: string
        cached:
          type: boolean
        expiresAt:
          type: string
          format: date-time
        title:
          type: string
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
  responses:
    BadRequest:
      description: 参数错误
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: 无效 API Key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: 超出配额
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
