openapi: 3.1.0
info:
  title: Mibyan API
  version: 1.0.0
  description: OpenAI-compatible text generation API with project-scoped Mibyan keys.
x-mibyan-async-jobs: not-exposed
servers:
  - url: "{baseUrl}"
    variables:
      baseUrl:
        default: https://api.mibyanai.com
        description: Canonical API origin discovered from the current deployment. Override in non-production environments.
security:
  - bearerAuth: []
paths:
  /v1/models:
    get:
      operationId: listModels
      summary: List models available to the key's project
      responses:
        "200":
          description: Model list
          headers:
            x-request-id: { $ref: "#/components/headers/RequestId" }
            x-mibyan-api-version: { $ref: "#/components/headers/ApiVersion" }
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ModelList" }
        "401": { $ref: "#/components/responses/ApiError" }
        "403": { $ref: "#/components/responses/ApiError" }
  /v1/chat/completions:
    post:
      operationId: createChatCompletion
      summary: Create a chat completion
      description: Cancelling the HTTP request cancels the upstream generation. This endpoint does not create asynchronous jobs, so callbacks and webhooks are not accepted.
      x-codeSamples:
        - lang: curl
          source: |
            curl https://api.mibyanai.com/v1/chat/completions \
              -H "Authorization: Bearer $MIBYAN_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{"model":"mibyan-4.1","messages":[{"role":"user","content":"Hello"}]}'
        - lang: JavaScript
          source: |
            import OpenAI from "openai";
            const client = new OpenAI({ apiKey: process.env.MIBYAN_API_KEY, baseURL: "https://api.mibyanai.com/v1" });
            const result = await client.chat.completions.create({ model: "mibyan-4.1", messages: [{ role: "user", content: "Hello" }] });
        - lang: Python
          source: |
            import os
            from openai import OpenAI
            client = OpenAI(api_key=os.environ["MIBYAN_API_KEY"], base_url="https://api.mibyanai.com/v1")
            result = client.chat.completions.create(model="mibyan-4.1", messages=[{"role": "user", "content": "Hello"}])
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ChatCompletionRequest" }
      responses:
        "200":
          description: Completion JSON or SSE stream
          headers:
            x-request-id: { $ref: "#/components/headers/RequestId" }
            x-mibyan-api-version: { $ref: "#/components/headers/ApiVersion" }
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ChatCompletion" }
            text/event-stream:
              schema:
                {
                  type: string,
                  description: "data-framed ChatCompletionChunk events followed by data: [DONE].",
                }
        "400": { $ref: "#/components/responses/ApiError" }
        "401": { $ref: "#/components/responses/ApiError" }
        "403": { $ref: "#/components/responses/ApiError" }
        "404": { $ref: "#/components/responses/ApiError" }
        "413": { $ref: "#/components/responses/ApiError" }
        "429": { $ref: "#/components/responses/ApiError" }
        "502": { $ref: "#/components/responses/ApiError" }
        "503": { $ref: "#/components/responses/ApiError" }
        "504": { $ref: "#/components/responses/ApiError" }
  /v1/responses:
    post:
      operationId: createResponse
      summary: Create a response
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ResponseRequest" }
      responses:
        "200":
          description: Response object or versioned SSE events
          headers:
            x-request-id: { $ref: "#/components/headers/RequestId" }
            x-mibyan-api-version: { $ref: "#/components/headers/ApiVersion" }
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Response" }
            text/event-stream:
              schema:
                {
                  type: string,
                  description: "Named response.output_text.delta events ending in response.completed.",
                }
        "400": { $ref: "#/components/responses/ApiError" }
        "401": { $ref: "#/components/responses/ApiError" }
        "403": { $ref: "#/components/responses/ApiError" }
        "404": { $ref: "#/components/responses/ApiError" }
        "429": { $ref: "#/components/responses/ApiError" }
        "502": { $ref: "#/components/responses/ApiError" }
        "503": { $ref: "#/components/responses/ApiError" }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Mibyan API key
  headers:
    RequestId:
      schema: { type: string, pattern: "^req_[a-f0-9]+$" }
      description: Correlation identifier propagated through the gateway and logs.
    ApiVersion:
      schema: { type: string, const: "2026-08-11" }
      description: Stable public boundary version implemented by this deployment.
  responses:
    ApiError:
      description: Mibyan API error
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorEnvelope" }
  schemas:
    ErrorEnvelope:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [message, type, code, request_id]
          properties:
            message: { type: string }
            type: { type: string }
            param: { type: [string, "null"] }
            code:
              type: string
              enum:
                [
                  invalid_api_key,
                  revoked_api_key,
                  expired_api_key,
                  project_archived,
                  permission_denied,
                  model_not_found,
                  model_not_allowed,
                  invalid_request,
                  method_not_allowed,
                  context_length_exceeded,
                  rate_limit_exceeded,
                  budget_exceeded,
                  insufficient_credits,
                  upstream_timeout,
                  upstream_unavailable,
                  upstream_timeout,
                  upstream_rate_limit,
                  upstream_model_not_found,
                  provider_auth_error,
                  invalid_upstream_response,
                  output_limit_exceeded,
                  server_misconfigured,
                  database_error,
                  internal_error,
                ]
            request_id: { type: string }
    Model:
      type: object
      required: [id, object, created, owned_by]
      properties:
        id: { const: mibyan-4.1 }
        object: { const: model }
        created: { type: integer }
        owned_by: { const: mibyan }
        status: { type: string, enum: [active, preview, limited, deprecated] }
    ModelList:
      type: object
      required: [object, data]
      properties:
        object: { const: list }
        data: { type: array, items: { $ref: "#/components/schemas/Model" } }
    Message:
      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 } }
            - { type: "null" }
      additionalProperties: true
    ChatCompletionRequest:
      type: object
      required: [model, messages]
      properties:
        model: { type: string }
        messages: { type: array, minItems: 1, items: { $ref: "#/components/schemas/Message" } }
        stream: { type: boolean, default: false }
        temperature: { type: number, minimum: 0, maximum: 2 }
        max_tokens: { type: integer, minimum: 1 }
        tools:
          type: array
          maxItems: 64
          items:
            type: object
            required: [type, function]
            properties:
              type: { const: function }
              function:
                type: object
                required: [name]
                properties:
                  name: { type: string, maxLength: 64 }
                  description: { type: string, maxLength: 4000 }
                  parameters: { type: object, additionalProperties: true }
        tool_choice:
          oneOf:
            - { type: string, enum: [auto, none, required] }
            - { type: object, additionalProperties: true }
        parallel_tool_calls: { type: boolean }
        response_format: { type: object, additionalProperties: true }
      additionalProperties: true
    Usage:
      type: object
      required: [prompt_tokens, completion_tokens, total_tokens]
      properties:
        prompt_tokens: { type: integer, minimum: 0 }
        completion_tokens: { type: integer, minimum: 0 }
        total_tokens: { type: integer, minimum: 0 }
    ChatCompletion:
      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
            required: [index, message, finish_reason]
            properties:
              index: { type: integer }
              message: { $ref: "#/components/schemas/Message" }
              finish_reason: { type: [string, "null"] }
        usage: { $ref: "#/components/schemas/Usage" }
    ResponseRequest:
      type: object
      required: [model, input]
      properties:
        model: { type: string }
        input:
          oneOf:
            - { type: string }
            - { type: array, items: { $ref: "#/components/schemas/Message" } }
        stream: { type: boolean, default: false }
        temperature: { type: number, minimum: 0, maximum: 2 }
        max_output_tokens: { type: integer, minimum: 1 }
      additionalProperties: true
    Response:
      type: object
      required: [id, object, status, model, output, usage]
      properties:
        id: { type: string }
        object: { const: response }
        created_at: { type: integer }
        status: { type: string, enum: [completed, failed, in_progress] }
        model: { type: string }
        output: { type: array, items: { type: object, additionalProperties: true } }
        usage:
          type: object
          properties:
            input_tokens: { type: integer, minimum: 0 }
            output_tokens: { type: integer, minimum: 0 }
            total_tokens: { type: integer, minimum: 0 }
