{
  "openapi": "3.1.0",
  "info": {
    "title": "oruk Speech API",
    "version": "1.0.0",
    "description": "English transcription, multilabel emotion, speaking-style, affect, and unified speech analysis."
  },
  "servers": [
    { "url": "https://speech-api.oruk.ai", "description": "Production" }
  ],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/v1/audio/transcriptions": {
      "post": {
        "operationId": "createTranscription",
        "summary": "Transcribe English audio",
        "parameters": [{ "$ref": "#/components/parameters/RequestId" }],
        "requestBody": { "$ref": "#/components/requestBodies/AudioRequest" },
        "responses": {
          "200": { "$ref": "#/components/responses/SpeechResult" },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/audio/emotions": {
      "post": {
        "operationId": "createEmotionAnalysis",
        "summary": "Classify multilabel emotion",
        "parameters": [{ "$ref": "#/components/parameters/RequestId" }],
        "requestBody": { "$ref": "#/components/requestBodies/AudioRequest" },
        "responses": {
          "200": { "$ref": "#/components/responses/SpeechResult" },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/audio/styles": {
      "post": {
        "operationId": "createStyleAnalysis",
        "summary": "Classify multilabel speaking style",
        "parameters": [{ "$ref": "#/components/parameters/RequestId" }],
        "requestBody": { "$ref": "#/components/requestBodies/AudioRequest" },
        "responses": {
          "200": { "$ref": "#/components/responses/SpeechResult" },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/audio/affect": {
      "post": {
        "operationId": "createAffectAnalysis",
        "summary": "Classify emotion and speaking style",
        "parameters": [{ "$ref": "#/components/parameters/RequestId" }],
        "requestBody": { "$ref": "#/components/requestBodies/AudioRequest" },
        "responses": {
          "200": { "$ref": "#/components/responses/SpeechResult" },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/audio/analysis": {
      "post": {
        "operationId": "createSpeechAnalysis",
        "summary": "Return transcript, emotion, style, segments, and tagged text",
        "parameters": [{ "$ref": "#/components/parameters/RequestId" }],
        "requestBody": { "$ref": "#/components/requestBodies/AudioRequest" },
        "responses": {
          "200": { "$ref": "#/components/responses/SpeechResult" },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List public models and supported tasks",
        "responses": {
          "200": { "description": "Model catalog", "content": { "application/json": { "schema": { "type": "object" } } } },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/pricing": {
      "get": {
        "operationId": "getPricing",
        "summary": "Get versioned prices",
        "security": [],
        "responses": {
          "200": { "description": "Pricing catalog", "content": { "application/json": { "schema": { "type": "object" } } } }
        }
      }
    },
    "/livez": {
      "get": {
        "operationId": "getLiveness",
        "summary": "Service liveness",
        "security": [],
        "responses": { "200": { "description": "Service process is live" } }
      }
    },
    "/readyz": {
      "get": {
        "operationId": "getReadiness",
        "summary": "Inference readiness",
        "security": [],
        "responses": { "200": { "description": "Inference dependencies are ready" } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "oruk API key" }
    },
    "parameters": {
      "RequestId": {
        "name": "X-Request-ID",
        "in": "header",
        "required": false,
        "description": "Unique request identifier. Reuse returns 409 and never creates a second debit.",
        "schema": { "type": "string", "maxLength": 128 }
      }
    },
    "requestBodies": {
      "AudioRequest": {
        "required": true,
        "content": {
          "multipart/form-data": {
            "schema": {
              "type": "object",
              "required": ["file"],
              "properties": {
                "file": { "type": "string", "format": "binary", "description": "WAV, FLAC, MP3, M4A, OGG, or WebM; maximum 30 MB and 60 minutes." },
                "model": { "type": "string", "enum": ["oruk-spectra-1", "oruk-spectra-2", "oruk-resonance"] }
              }
            }
          }
        }
      }
    },
    "responses": {
      "SpeechResult": {
        "description": "Speech result and measured usage",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SpeechResult" } } }
      },
      "Error": {
        "description": "Stable error envelope",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } }
      }
    },
    "schemas": {
      "Score": {
        "type": "object",
        "required": ["label", "score"],
        "properties": {
          "label": { "type": "string" },
          "score": { "type": "number", "minimum": 0, "maximum": 1 }
        }
      },
      "Word": {
        "type": "object",
        "required": ["word", "start", "end"],
        "properties": {
          "word": { "type": "string" },
          "start": { "type": "number", "minimum": 0 },
          "end": { "type": "number", "minimum": 0 },
          "confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 1 }
        }
      },
      "Segment": {
        "type": "object",
        "required": ["id", "start", "end", "emotions", "styles"],
        "properties": {
          "id": { "type": "integer" },
          "start": { "type": "number", "minimum": 0 },
          "end": { "type": "number", "minimum": 0 },
          "text": { "type": ["string", "null"] },
          "tagged_text": { "type": ["string", "null"] },
          "words": { "type": "array", "items": { "$ref": "#/components/schemas/Word" } },
          "emotions": { "type": "array", "items": { "$ref": "#/components/schemas/Score" } },
          "styles": { "type": "array", "items": { "$ref": "#/components/schemas/Score" } }
        }
      },
      "Usage": {
        "type": "object",
        "required": ["audio_seconds", "billable_seconds", "rate_per_minute_usd", "estimated_cost_usd", "pricing_version"],
        "properties": {
          "audio_seconds": { "type": "number", "minimum": 0 },
          "billable_seconds": { "type": "number", "minimum": 1 },
          "rate_per_minute_usd": { "type": "string" },
          "estimated_cost_usd": { "type": "string" },
          "pricing_version": { "type": "string" }
        }
      },
      "SpeechResult": {
        "type": "object",
        "required": ["id", "object", "task", "model", "duration", "emotions", "styles", "segments", "usage"],
        "properties": {
          "id": { "type": "string" },
          "object": { "const": "speech.result" },
          "task": { "type": "string", "enum": ["transcription", "emotion", "style", "affect", "analysis"] },
          "model": { "type": "string" },
          "text": { "type": ["string", "null"] },
          "tagged_text": { "type": ["string", "null"] },
          "language": { "type": ["string", "null"] },
          "duration": { "type": "number", "minimum": 0 },
          "emotions": { "type": "array", "items": { "$ref": "#/components/schemas/Score" } },
          "styles": { "type": "array", "items": { "$ref": "#/components/schemas/Score" } },
          "segments": { "type": "array", "items": { "$ref": "#/components/schemas/Segment" } },
          "usage": { "$ref": "#/components/schemas/Usage" }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["type", "code", "message"],
            "properties": {
              "type": { "type": "string" },
              "code": { "type": "string" },
              "message": { "type": "string" },
              "param": { "type": ["string", "null"] },
              "request_id": { "type": ["string", "null"] }
            }
          }
        }
      }
    }
  }
}
