openapi: "3.1.0"
info:
  title: NovaKit API
  description: Unified AI API for chat completions, image generation, video generation, audio processing, and more. OpenAI SDK compatible.
  version: "1.0.0"
  contact:
    name: NovaKit Support
    url: "https://www.novakit.ai/contact"
    email: support@novakit.ai
  license:
    name: MIT
    url: "https://opensource.org/licenses/MIT"
servers:
  - url: "https://www.novakit.ai/api/v1"
    description: Production server
security:
  - BearerAuth: []
tags:
  - name: Chat
    description: Chat completion endpoints for text generation
  - name: Images
    description: Image generation and editing endpoints
  - name: Video
    description: Video generation endpoints
  - name: Audio
    description: Text-to-speech and speech-to-text endpoints
  - name: Music
    description: Music generation endpoints
  - name: Models
    description: Model listing and information
  - name: Jobs
    description: Async job management
paths:
  /chat/completions:
    post:
      operationId: createChatCompletion
      tags:
        - Chat
      summary: Create chat completion
      description: Creates a model response for the given chat conversation. Supports streaming via SSE.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChatCompletionRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChatCompletionResponse"
            text/event-stream:
              schema:
                type: string
                description: Server-sent events stream
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
        429:
          $ref: "#/components/responses/RateLimited"
  /images/generations:
    post:
      operationId: createImage
      tags:
        - Images
      summary: Generate image
      description: Creates an image given a text prompt using Flux, Stable Diffusion, and other models.
      parameters:
        - name: async
          in: query
          description: Run generation asynchronously and return a job ID
          schema:
            type: boolean
            default: false
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ImageGenerationRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ImageGenerationResponse"
                  - $ref: "#/components/schemas/AsyncJobResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
        429:
          $ref: "#/components/responses/RateLimited"
  /images/edits:
    post:
      operationId: editImage
      tags:
        - Images
      summary: Edit image
      description: Edits an existing image based on a text prompt. Supports inpainting and outpainting.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ImageEditRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ImageGenerationResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
  /videos/generations:
    post:
      operationId: createVideo
      tags:
        - Video
      summary: Generate video
      description: Creates a video from a text prompt or source image using MiniMax, Luma, and other models.
      parameters:
        - name: async
          in: query
          description: Run generation asynchronously (recommended for video)
          schema:
            type: boolean
            default: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VideoGenerationRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/VideoGenerationResponse"
                  - $ref: "#/components/schemas/AsyncJobResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
        429:
          $ref: "#/components/responses/RateLimited"
  /audio/speech:
    post:
      operationId: createSpeech
      tags:
        - Audio
      summary: Text to speech
      description: Generates audio from input text using AI voice synthesis. Supports voice cloning.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TextToSpeechRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TextToSpeechResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
  /audio/transcriptions:
    post:
      operationId: createTranscription
      tags:
        - Audio
      summary: Speech to text
      description: Transcribes audio into text with support for multiple languages and speaker detection.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SpeechToTextRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SpeechToTextResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
  /music/generations:
    post:
      operationId: createMusic
      tags:
        - Music
      summary: Generate music
      description: Creates original music tracks from text descriptions using Stable Audio and other models.
      parameters:
        - name: async
          in: query
          description: Run generation asynchronously (recommended)
          schema:
            type: boolean
            default: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MusicGenerationRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/MusicGenerationResponse"
                  - $ref: "#/components/schemas/AsyncJobResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
  /models:
    get:
      operationId: listModels
      tags:
        - Models
      summary: List models
      description: Lists all available models and their capabilities, grouped by category.
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ModelsListResponse"
        401:
          $ref: "#/components/responses/Unauthorized"
  /jobs/{jobId}:
    get:
      operationId: getJob
      tags:
        - Jobs
      summary: Get job status
      description: Retrieves the status and result of an async job.
      parameters:
        - name: jobId
          in: path
          required: true
          description: The job ID returned from an async request
          schema:
            type: string
        - name: poll
          in: query
          description: Enable long polling - waits up to 30s for job completion
          schema:
            type: boolean
            default: false
      responses:
        200:
          description: Job status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JobStatusResponse"
        401:
          $ref: "#/components/responses/Unauthorized"
        404:
          $ref: "#/components/responses/NotFound"
  /embeddings:
    post:
      operationId: createEmbedding
      tags:
        - Chat
      summary: Create embeddings
      description: Creates an embedding vector representing the input text.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EmbeddingRequest"
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmbeddingResponse"
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: API key authentication. Get your key from the dashboard.
  schemas:
    ChatCompletionRequest:
      type: object
      required:
        - messages
      properties:
        messages:
          type: array
          description: A list of messages comprising the conversation
          items:
            $ref: "#/components/schemas/ChatMessage"
        model:
          type: string
          description: Model ID to use
          default: openai/gpt-4o-mini
          examples:
            - openai/gpt-4o
            - openai/gpt-4o-mini
            - anthropic/claude-3.5-sonnet
        temperature:
          type: number
          description: Sampling temperature (0-2)
          minimum: 0
          maximum: 2
          default: 0.7
        max_tokens:
          type: integer
          description: Maximum tokens to generate
          default: 2048
        stream:
          type: boolean
          description: Enable SSE streaming
          default: false
        web_search:
          type: boolean
          description: Enable web search grounding
          default: false
    ChatMessage:
      type: object
      required:
        - role
        - content
      properties:
        role:
          type: string
          enum:
            - system
            - user
            - assistant
          description: The role of the message author
        content:
          type: string
          description: The content of the message
        images:
          type: array
          description: Array of image URLs for vision models
          items:
            type: string
            format: uri
    ChatCompletionResponse:
      type: object
      properties:
        id:
          type: string
          description: Unique completion ID
        object:
          type: string
          enum:
            - chat.completion
        created:
          type: integer
          description: Unix timestamp
        model:
          type: string
          description: Model used
        model_tier:
          type: string
          enum:
            - fast
            - standard
            - premium
        choices:
          type: array
          items:
            type: object
            properties:
              index:
                type: integer
              message:
                $ref: "#/components/schemas/ChatMessage"
              finish_reason:
                type: string
                enum:
                  - stop
                  - length
                  - content_filter
        usage:
          $ref: "#/components/schemas/Usage"
    ImageGenerationRequest:
      type: object
      required:
        - prompt
      properties:
        prompt:
          type: string
          description: Text description of the image
          maxLength: 4000
        model:
          type: string
          description: Model ID
          default: fal-ai/flux/dev
        size:
          type: string
          enum:
            - "512x512"
            - "1024x1024"
            - "1792x1024"
            - "1024x1792"
          default: "1024x1024"
        n:
          type: integer
          description: Number of images (1-10)
          minimum: 1
          maximum: 10
          default: 1
        upscale:
          type: string
          enum:
            - "2x"
            - "4x"
          nullable: true
          description: Upscale factor
        style:
          type: string
          enum:
            - vivid
            - natural
          default: vivid
        negative_prompt:
          type: string
          nullable: true
          description: What to avoid in the image
        seed:
          type: integer
          nullable: true
          description: Random seed for reproducibility
    ImageGenerationResponse:
      type: object
      properties:
        created:
          type: integer
        data:
          type: array
          items:
            type: object
            properties:
              url:
                type: string
                format: uri
              revised_prompt:
                type: string
              width:
                type: integer
              height:
                type: integer
        model:
          type: string
        model_tier:
          type: string
        usage:
          $ref: "#/components/schemas/Usage"
    ImageEditRequest:
      type: object
      required:
        - image
        - prompt
      properties:
        image:
          type: string
          format: uri
          description: URL of the image to edit
        prompt:
          type: string
          description: Edit instructions
        mask:
          type: string
          format: uri
          nullable: true
          description: Mask image URL for inpainting
        model:
          type: string
          default: fal-ai/flux/dev/image-to-image
        size:
          type: string
          enum:
            - "512x512"
            - "1024x1024"
          default: "1024x1024"
    VideoGenerationRequest:
      type: object
      required:
        - prompt
      properties:
        prompt:
          type: string
          description: Text description of the video
        model:
          type: string
          default: fal-ai/minimax/video-01
        duration_seconds:
          type: number
          minimum: 1
          maximum: 10
          default: 5
        resolution:
          type: string
          enum:
            - "720p"
            - "1080p"
            - "4k"
          default: "720p"
        fps:
          type: integer
          enum:
            - 30
            - 60
          default: 30
        aspect_ratio:
          type: string
          enum:
            - "16:9"
            - "9:16"
            - "1:1"
            - "4:3"
            - "3:4"
          default: "16:9"
        mode:
          type: string
          enum:
            - text_to_video
            - image_to_video
            - video_to_video
          default: text_to_video
        source_image:
          type: string
          format: uri
          nullable: true
          description: Image URL for image-to-video mode
        source_video:
          type: string
          format: uri
          nullable: true
          description: Video URL for video-to-video mode
        negative_prompt:
          type: string
          nullable: true
        seed:
          type: integer
          nullable: true
        prompt_optimizer:
          type: boolean
          default: true
          description: Enhance prompt (MiniMax)
        loop:
          type: boolean
          default: false
          description: Create looping video (Luma)
    VideoGenerationResponse:
      type: object
      properties:
        created:
          type: integer
        data:
          type: object
          properties:
            url:
              type: string
              format: uri
            duration_seconds:
              type: number
            width:
              type: integer
            height:
              type: integer
        model:
          type: string
        model_tier:
          type: string
        usage:
          $ref: "#/components/schemas/Usage"
    TextToSpeechRequest:
      type: object
      required:
        - input
      properties:
        input:
          type: string
          description: Text to synthesize
          maxLength: 10000
        model:
          type: string
          default: fal-ai/f5-tts
        voice:
          type: string
          enum:
            - alloy
            - echo
            - fable
            - onyx
            - nova
            - shimmer
          default: nova
        speed:
          type: number
          minimum: 0.25
          maximum: 4
          default: 1
        response_format:
          type: string
          enum:
            - mp3
            - wav
            - opus
            - aac
          default: mp3
        reference_audio:
          type: string
          format: uri
          nullable: true
          description: URL for voice cloning
        reference_text:
          type: string
          nullable: true
          description: Transcript of reference audio
    TextToSpeechResponse:
      type: object
      properties:
        created:
          type: integer
        audio_url:
          type: string
          format: uri
        duration_seconds:
          type: number
        character_count:
          type: integer
        model:
          type: string
        model_tier:
          type: string
        usage:
          $ref: "#/components/schemas/Usage"
    SpeechToTextRequest:
      type: object
      required:
        - file
      properties:
        file:
          type: string
          description: Audio URL or base64 data
        model:
          type: string
          default: fal-ai/whisper
        language:
          type: string
          default: auto
          description: ISO language code or 'auto'
        response_format:
          type: string
          enum:
            - json
            - text
            - srt
            - vtt
          default: json
        timestamp_granularities:
          type: array
          items:
            type: string
            enum:
              - segment
              - word
          default:
            - segment
        diarization:
          type: boolean
          default: false
          description: Enable speaker detection
        translation:
          type: boolean
          default: false
          description: Translate to English
    SpeechToTextResponse:
      type: object
      properties:
        text:
          type: string
        segments:
          type: array
          items:
            type: object
            properties:
              start:
                type: number
              end:
                type: number
              text:
                type: string
              speaker:
                type: string
                nullable: true
        words:
          type: array
          items:
            type: object
            properties:
              word:
                type: string
              start:
                type: number
              end:
                type: number
        language:
          type: string
        duration:
          type: number
        model:
          type: string
        model_tier:
          type: string
        usage:
          $ref: "#/components/schemas/Usage"
    MusicGenerationRequest:
      type: object
      required:
        - prompt
      properties:
        prompt:
          type: string
          description: Description of the music
        model:
          type: string
          default: fal-ai/stable-audio
        duration_seconds:
          type: number
          minimum: 1
          maximum: 47
          default: 30
        mode:
          type: string
          enum:
            - text_to_music
            - audio_to_audio
          default: text_to_music
        source_audio:
          type: string
          format: uri
          nullable: true
        output_format:
          type: string
          enum:
            - mp3
            - wav
          default: mp3
        negative_prompt:
          type: string
          nullable: true
    MusicGenerationResponse:
      type: object
      properties:
        created:
          type: integer
        data:
          type: object
          properties:
            audio_url:
              type: string
              format: uri
            duration_seconds:
              type: number
        model:
          type: string
        model_tier:
          type: string
        usage:
          $ref: "#/components/schemas/Usage"
    EmbeddingRequest:
      type: object
      required:
        - input
      properties:
        input:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
          description: Text to embed
        model:
          type: string
          default: text-embedding-3-small
        dimensions:
          type: integer
          description: Output dimensions
    EmbeddingResponse:
      type: object
      properties:
        object:
          type: string
          enum:
            - list
        data:
          type: array
          items:
            type: object
            properties:
              object:
                type: string
                enum:
                  - embedding
              index:
                type: integer
              embedding:
                type: array
                items:
                  type: number
        model:
          type: string
        usage:
          type: object
          properties:
            prompt_tokens:
              type: integer
            total_tokens:
              type: integer
    ModelsListResponse:
      type: object
      properties:
        object:
          type: string
          enum:
            - list
        data:
          type: array
          items:
            $ref: "#/components/schemas/Model"
    Model:
      type: object
      properties:
        id:
          type: string
        object:
          type: string
          enum:
            - model
        created:
          type: integer
        owned_by:
          type: string
        category:
          type: string
          enum:
            - chat
            - image
            - video
            - audio
            - music
            - embedding
        capabilities:
          type: array
          items:
            type: string
    AsyncJobResponse:
      type: object
      properties:
        id:
          type: string
          description: Job ID for polling
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
        created:
          type: integer
        model:
          type: string
        estimated_credits:
          type: integer
    JobStatusResponse:
      type: object
      properties:
        id:
          type: string
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
        progress:
          type: integer
          minimum: 0
          maximum: 100
        created:
          type: integer
        completed:
          type: integer
          nullable: true
        model:
          type: string
        outputData:
          type: object
          nullable: true
          description: Result data when completed
        errorMessage:
          type: string
          nullable: true
          description: Error message if failed
        usage:
          $ref: "#/components/schemas/Usage"
    Usage:
      type: object
      properties:
        credits_used:
          type: integer
        credits_breakdown:
          type: object
          additionalProperties:
            type: integer
        prompt_tokens:
          type: integer
        completion_tokens:
          type: integer
        total_tokens:
          type: integer
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
            type:
              type: string
            code:
              type: string
  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Unauthorized - invalid or missing API key
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    RateLimited:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"