openapi: 3.1.0
info:
  title: AIToken API
  version: 1.0.0
  description: OpenAI-compatible model catalog and chat completion gateway.
servers:
  - url: https://api.tawsiya.cn/v1
    description: AIToken production gateway
security:
  - bearerAuth: []
tags:
  - name: Models
    description: Available AI models
  - name: Chat
    description: Chat completions
  - name: Account
    description: API key account and usage information
paths:
  /models:
    get:
      tags: [Models]
      summary: List available models
      operationId: listModels
      responses:
        "200":
          description: Available model list
          content:
            application/json:
              schema:
                type: object
                required: [object, data]
                properties:
                  object:
                    type: string
                    const: list
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Model"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"
  /chat/completions:
    post:
      tags: [Chat]
      summary: Create a chat completion
      operationId: createChatCompletion
      parameters:
        - name: X-Request-ID
          in: header
          required: false
          description: Optional client-generated request identifier.
          schema:
            type: string
            maxLength: 40
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChatCompletionRequest"
            examples:
              basic:
                value:
                  model: gpt-5-mini
                  messages:
                    - role: user
                      content: Hello
      responses:
        "200":
          description: Completion response or an SSE stream when stream is true.
          headers:
            X-Request-ID:
              description: Gateway request identifier for support and log lookup.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChatCompletionResponse"
            text/event-stream:
              schema:
                type: string
                description: Server-sent events ending with data colon space open bracket DONE close bracket.
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/InsufficientBalance"
        "429":
          $ref: "#/components/responses/RateLimited"
        "502":
          $ref: "#/components/responses/UpstreamError"
  /account:
    get:
      tags: [Account]
      summary: Get account and API key information
      operationId: getAccount
      responses:
        "200":
          description: Current API key account, balance, limits, and subscription.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /usage:
    get:
      tags: [Account]
      summary: Get API key usage
      operationId: getUsage
      parameters:
        - name: period
          in: query
          required: false
          description: Reporting window. Defaults to 24h.
          schema:
            type: string
            enum: [24h, 7d, 30d]
            default: 24h
      responses:
        "200":
          description: Usage summary and the latest request records.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: Use the API key created in the AIToken user console.
  schemas:
    Model:
      type: object
      required: [id, object, created, owned_by]
      properties:
        id:
          type: string
          examples: [gpt-5-mini]
        object:
          type: string
          const: model
        created:
          type: integer
        owned_by:
          type: string
        model_type:
          type: string
          description: Model capability type such as chat, reasoning, vision, or audio.
        group:
          type: [string, "null"]
          description: Configured model group code.
    ChatMessage:
      type: object
      required: [role, content]
      properties:
        role:
          type: string
          enum: [system, developer, user, assistant, tool]
        content:
          oneOf:
            - type: string
            - type: array
              items:
                type: object
                additionalProperties: true
        name:
          type: string
        tool_call_id:
          type: string
    ChatCompletionRequest:
      type: object
      required: [model, messages]
      properties:
        model:
          type: string
        messages:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/ChatMessage"
        stream:
          type: boolean
          default: false
        temperature:
          type: number
          minimum: 0
          maximum: 2
        max_tokens:
          type: integer
          minimum: 1
        top_p:
          type: number
          minimum: 0
          maximum: 1
      additionalProperties: true
    Usage:
      type: object
      properties:
        prompt_tokens:
          type: integer
        completion_tokens:
          type: integer
        total_tokens:
          type: integer
    ChatCompletionResponse:
      type: object
      required: [id, object, created, model, choices]
      properties:
        id:
          type: string
        object:
          type: string
        created:
          type: integer
        model:
          type: string
        choices:
          type: array
          items:
            type: object
            additionalProperties: true
        usage:
          $ref: "#/components/schemas/Usage"
      additionalProperties: true
    AccountResponse:
      type: object
      required: [object, user, api_key, balance, subscription]
      properties:
        object:
          type: string
          const: account
        user:
          type: object
          additionalProperties: true
        api_key:
          type: object
          additionalProperties: true
        balance:
          type: object
          additionalProperties: true
        subscription:
          oneOf:
            - type: object
              additionalProperties: true
            - type: "null"
    UsageResponse:
      type: object
      required: [object, period, from, to, summary, data]
      properties:
        object:
          type: string
          const: usage
        period:
          type: string
          enum: [24h, 7d, 30d]
        from:
          type: string
          format: date-time
        to:
          type: string
          format: date-time
        summary:
          type: object
          additionalProperties: true
        data:
          type: array
          items:
            type: object
            additionalProperties: true
    ErrorDetail:
      type: object
      required: [message, type, code]
      properties:
        message:
          type: string
        type:
          type: string
        code:
          type: string
        param:
          type: [string, "null"]
    ErrorResponse:
      type: object
      required: [error, request_id]
      properties:
        error:
          $ref: "#/components/schemas/ErrorDetail"
        request_id:
          type: string
  responses:
    BadRequest:
      description: Invalid request payload
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    Unauthorized:
      description: Missing, invalid, expired, or revoked API key
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    InsufficientBalance:
      description: The account does not have enough available balance
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    RateLimited:
      description: RPM, concurrency, or daily budget limit exceeded
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    UpstreamError:
      description: No healthy upstream channel or upstream request failed
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
