openapi: 3.1.0
info:
  title: Rakita API
  version: 1.1.0
  description: >
    Tek API anahtarıyla gerçek zamanlı konuşma tanıma, sohbet üretimi,
    streaming ses sentezi ve izinli referans kayıttan ses klonlama.
servers:
  - url: https://rakitaapi.ceyberdigital.com
security:
  - bearerAuth: []
paths:
  /v1/chat/completions:
    post:
      operationId: createChatCompletion
      summary: Sohbet yanıtı üretir
      description: stream=true olduğunda text/event-stream döndürür.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChatRequest"
      responses:
        "200":
          description: JSON veya SSE sohbet yanıtı.
          content:
            application/json: {}
            text/event-stream: {}
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/audio/speech:
    post:
      operationId: createSpeech
      summary: Metinden ses üretir
      description: >
        stream=false iken binary ses; stream=true iken speech.audio.delta
        ve speech.audio.done SSE olayları döndürür.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SpeechRequest"
      responses:
        "200":
          description: Üretilen ses veya SSE ses akışı.
          content:
            audio/wav: {}
            audio/mpeg: {}
            application/octet-stream: {}
            text/event-stream: {}
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/voices:
    get:
      operationId: listVoices
      summary: Çalışma alanına ait sesleri listeler
      responses:
        "200":
          description: Varsayılan ve özel seslerin listesi.
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    const: list
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Voice"
        "401":
          $ref: "#/components/responses/Unauthorized"
    post:
      operationId: createVoice
      summary: Referans kayıttan özel ses oluşturur
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [name, sample, consent]
              properties:
                name:
                  type: string
                  maxLength: 120
                sample:
                  type: string
                  format: binary
                  description: WAV, MP3, M4A, OGG veya WebM; en fazla 15 MB.
                consent:
                  type: boolean
                  const: true
                  description: Referans sesi kullanma yetkisinin onayı.
                reference_text:
                  type: string
                  maxLength: 2000
                  description: Referans kaydın konuşma dökümü.
      responses:
        "201":
          description: Oluşturulan özel ses.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Voice"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /v1/voices/{voiceId}:
    delete:
      operationId: deleteVoice
      summary: Özel sesi siler
      parameters:
        - name: voiceId
          in: path
          required: true
          schema:
            type: string
            pattern: "^voice_"
      responses:
        "204":
          description: Ses silindi.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          description: Ses bulunamadı.
  /v1/usage:
    get:
      operationId: getUsage
      summary: Günlük ve toplam kullanımı döndürür
      parameters:
        - name: days
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 90
            default: 30
      responses:
        "200":
          description: Model ve metrik bazında kullanım özeti.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageSummary"
        "401":
          $ref: "#/components/responses/Unauthorized"
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Rakita API key
  responses:
    InvalidRequest:
      description: İstek gövdesi veya parametreleri geçersiz.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    Unauthorized:
      description: API anahtarı geçersiz veya etkin değil.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    Unavailable:
      description: Model hizmeti geçici olarak kullanılamıyor.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
  schemas:
    ChatMessage:
      type: object
      required: [role, content]
      properties:
        role:
          type: string
          enum: [system, user, assistant, tool]
        content: {}
        name:
          type: string
          maxLength: 128
        tool_call_id:
          type: string
    ChatRequest:
      type: object
      required: [model, messages]
      properties:
        model:
          type: string
          const: rakita-llm
        messages:
          type: array
          minItems: 1
          maxItems: 256
          items:
            $ref: "#/components/schemas/ChatMessage"
        stream:
          type: boolean
          default: false
        max_tokens:
          type: integer
          minimum: 1
          maximum: 8192
        temperature:
          type: number
          minimum: 0
          maximum: 2
        top_p:
          type: number
          minimum: 0
          maximum: 1
    SpeechRequest:
      type: object
      required: [model, input]
      properties:
        model:
          type: string
          const: rakita-tts
        input:
          type: string
          minLength: 1
          maxLength: 5000
        voice:
          type: string
          default: rakita-default
          description: rakita-default veya POST /v1/voices çıktısındaki voice_ kimliği.
        response_format:
          type: string
          enum: [wav, mp3, pcm]
          default: wav
        speed:
          type: number
          minimum: 0.5
          maximum: 2
          default: 1
        stream:
          type: boolean
          default: false
          description: >
            true ise response_format wav/pcm ve speed 1 olmalıdır.
    Voice:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        status:
          type: string
          enum: [processing, ready, failed]
        created_at:
          type: [string, "null"]
          format: date-time
    UsageRow:
      type: object
      properties:
        model:
          type: string
          enum: [rakita-stt, rakita-llm, rakita-tts]
        metric:
          type: string
          enum: [socket_seconds, input_tokens, output_tokens, characters]
        quantity:
          type: number
    UsageSummary:
      type: object
      properties:
        object:
          const: usage_summary
        period_days:
          type: integer
        totals:
          type: array
          items:
            $ref: "#/components/schemas/UsageRow"
        daily:
          type: array
          items:
            allOf:
              - $ref: "#/components/schemas/UsageRow"
              - type: object
                properties:
                  day:
                    type: string
                    format: date
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          required: [code, message, request_id]
          properties:
            code:
              type: string
            message:
              type: string
            request_id:
              type: string
x-websockets:
  authentication:
    server: "Authorization: Bearer <RAKITA_API_KEY>"
    browserProtocols: ["rakita", "<RAKITA_API_KEY>"]
  endpoints:
    - url: wss://rakitaapi.ceyberdigital.com/v1/realtime/transcriptions
      model: rakita-stt
      input: >
        İlk JSON yapılandırması, ardından binary ses ve type=finalize.
        Final <fin> tokenından sonra tek seferlik istemci bağlantıyı 1000
        koduyla kapatır; finalize tek başına oturumu kapatmaz.
      output: "session.ready, token yanıtları, finished veya error."
    - url: wss://rakitaapi.ceyberdigital.com/v1/realtime/chat
      model: rakita-llm
      input: "response.create türünde chat completion JSON."
      output: "session.ready, response.start, response.chunk, response.done."
    - url: wss://rakitaapi.ceyberdigital.com/v1/realtime/speech
      model: rakita-tts
      input: "session.config, input.text ve input.done JSON olayları."
      output: "audio.start, binary ses frame'leri, audio.usage ve audio.done."
