{
  "openapi": "3.1.0",
  "info": {
    "title": "OneOver Business API",
    "version": "1.0.0",
    "description": "REST API for chat, images, video, audio, models, and usage reporting. Authenticate with Bearer oo_live_* API keys.",
    "contact": {
      "name": "OneOver",
      "url": "https://oneover.com/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://oneover.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.oneover.com/functions/v1",
      "description": "Production"
    }
  ],
  "security": [{ "BearerApiKey": [] }],
  "tags": [
    { "name": "chat", "description": "Stateless chat completions" },
    { "name": "images", "description": "Image generation" },
    { "name": "video", "description": "Async video generation" },
    { "name": "audio", "description": "Speech and music generation" },
    { "name": "models", "description": "Model catalog" },
    { "name": "usage", "description": "Balance and usage reporting" }
  ],
  "paths": {
    "/api-v1-chat": {
      "post": {
        "operationId": "chatCompletion",
        "tags": ["chat"],
        "summary": "Stateless chat completion",
        "description": "Send messages to any text model. Set stream=true for Server-Sent Events.",
        "security": [{ "BearerApiKey": ["chat"] }],
        "parameters": [{ "$ref": "#/components/parameters/MemberUserId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ChatRequest" },
              "example": {
                "model": "gpt-5.6-sol",
                "messages": [{ "role": "user", "content": "Hello" }],
                "stream": false,
                "max_tokens": 1024
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion (JSON or text/event-stream when stream=true)",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChatResponse" }
              },
              "text/event-stream": {
                "schema": { "type": "string", "description": "SSE events: connection_established, content, done, error" }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      }
    },
    "/api-v1-images": {
      "post": {
        "operationId": "generateImage",
        "tags": ["images"],
        "summary": "Generate an image",
        "security": [{ "BearerApiKey": ["images"] }],
        "parameters": [{ "$ref": "#/components/parameters/MemberUserId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ImageRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated image URL",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ImageResponse" }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      }
    },
    "/api-v1-video": {
      "post": {
        "operationId": "submitVideo",
        "tags": ["video"],
        "summary": "Submit async video generation job",
        "security": [{ "BearerApiKey": ["video"] }],
        "parameters": [{ "$ref": "#/components/parameters/MemberUserId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/VideoSubmitRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VideoSubmitResponse" }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      },
      "get": {
        "operationId": "pollVideo",
        "tags": ["video"],
        "summary": "Poll video job status",
        "security": [{ "BearerApiKey": ["video"] }],
        "parameters": [
          { "$ref": "#/components/parameters/MemberUserId" },
          {
            "name": "request_id",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "request_id from submit response"
          }
        ],
        "responses": {
          "200": {
            "description": "Job status",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VideoPollResponse" }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      }
    },
    "/api-v1-audio": {
      "post": {
        "operationId": "generateAudio",
        "tags": ["audio"],
        "summary": "Generate speech or music",
        "security": [{ "BearerApiKey": ["audio"] }],
        "parameters": [{ "$ref": "#/components/parameters/MemberUserId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/AudioRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated audio URL",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AudioResponse" }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      }
    },
    "/api-v1-models": {
      "get": {
        "operationId": "listModels",
        "tags": ["models"],
        "summary": "List org-visible models",
        "security": [{ "BearerApiKey": ["usage"] }],
        "parameters": [
          { "$ref": "#/components/parameters/MemberUserId" },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["text", "image", "video"] },
            "description": "Filter by model type"
          }
        ],
        "responses": {
          "200": {
            "description": "Model catalog",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ModelsResponse" }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      }
    },
    "/api-v1-usage": {
      "get": {
        "operationId": "getUsage",
        "tags": ["usage"],
        "summary": "Balance or usage reporting",
        "security": [{ "BearerApiKey": ["usage"] }],
        "parameters": [
          { "$ref": "#/components/parameters/MemberUserId" },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["balance", "usage"], "default": "usage" }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "maximum": 90, "default": 30 }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 }
          }
        ],
        "responses": {
          "200": {
            "description": "Balance or usage data",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    { "$ref": "#/components/schemas/BalanceResponse" },
                    { "$ref": "#/components/schemas/UsageResponse" }
                  ]
                }
              }
            }
          },
          "default": { "$ref": "#/components/responses/ApiError" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key starting with oo_live_. Scopes: chat, images, video, audio, usage."
      }
    },
    "parameters": {
      "MemberUserId": {
        "name": "X-Member-User-Id",
        "in": "header",
        "required": false,
        "schema": { "type": "string", "format": "uuid" },
        "description": "Optional internal user UUID for per-member attribution"
      }
    },
    "responses": {
      "ApiError": {
        "description": "API error",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorEnvelope" }
          }
        }
      }
    },
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthorized",
                  "invalid_key",
                  "key_not_found",
                  "org_inactive",
                  "scope_denied",
                  "rate_limit_exceeded",
                  "insufficient_credits",
                  "model_not_allowed",
                  "validation_error",
                  "internal_error"
                ]
              },
              "message": { "type": "string" },
              "request_id": { "type": "string", "format": "uuid", "nullable": true }
            }
          }
        }
      },
      "Balance": {
        "type": "object",
        "properties": {
          "subscription": { "type": "integer" },
          "anytime": { "type": "integer" }
        }
      },
      "ChatRequest": {
        "type": "object",
        "required": ["model", "messages"],
        "properties": {
          "model": { "type": "string" },
          "messages": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["role", "content"],
              "properties": {
                "role": { "type": "string", "enum": ["system", "user", "assistant"] },
                "content": { "type": "string" }
              }
            }
          },
          "stream": { "type": "boolean", "default": false },
          "max_tokens": { "type": "integer" }
        }
      },
      "ChatResponse": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "model": { "type": "string" },
          "message": {
            "type": "object",
            "properties": {
              "role": { "type": "string" },
              "content": { "type": "string" }
            }
          },
          "credits_charged": { "type": "integer" },
          "balance": { "$ref": "#/components/schemas/Balance" },
          "efficiency": { "type": "object", "additionalProperties": true }
        }
      },
      "ImageRequest": {
        "type": "object",
        "required": ["model", "prompt"],
        "properties": {
          "model": { "type": "string" },
          "prompt": { "type": "string" },
          "negative_prompt": { "type": "string" },
          "aspect_ratio": { "type": "string" },
          "resolution_tier": { "type": "string", "enum": ["1k", "2k", "4k"] }
        }
      },
      "ImageResponse": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "model": { "type": "string" },
          "image_url": { "type": "string", "format": "uri" },
          "credits_charged": { "type": "integer" },
          "balance": { "$ref": "#/components/schemas/Balance" }
        }
      },
      "VideoSubmitRequest": {
        "type": "object",
        "required": ["model"],
        "properties": {
          "model": { "type": "string" },
          "prompt": { "type": "string" },
          "duration": { "type": "number" },
          "resolution": { "type": "string" },
          "aspect_ratio": { "type": "string" },
          "generate_audio": { "type": "boolean" },
          "video_draft": { "type": "boolean" },
          "reference_image": { "type": "string", "description": "Base64-encoded image" },
          "reference_video": { "type": "string", "description": "Base64-encoded video" },
          "reference_audio": { "type": "string", "description": "Base64-encoded audio" },
          "keep_audio": { "type": "boolean" },
          "omni_task": {
            "type": "string",
            "enum": ["text_to_video", "image_to_video", "reference_to_video", "edit"]
          },
          "seed": { "type": "integer" }
        }
      },
      "VideoSubmitResponse": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "enum": ["processing"] },
          "model": { "type": "string" },
          "credits_estimate": { "type": "integer" }
        }
      },
      "VideoPollResponse": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "enum": ["processing", "complete", "failed"] },
          "model": { "type": "string" },
          "video_url": { "type": "string", "format": "uri" },
          "provider_status": { "type": "string" },
          "credits_charged": { "type": "integer" },
          "balance": { "$ref": "#/components/schemas/Balance" }
        }
      },
      "AudioRequest": {
        "type": "object",
        "required": ["model", "prompt"],
        "properties": {
          "model": { "type": "string" },
          "prompt": { "type": "string" },
          "audio_kind": { "type": "string", "enum": ["speech", "music"], "default": "speech" },
          "voice": { "type": "string" },
          "speakers": { "type": "array", "items": { "type": "string" } },
          "speed": { "type": "number" },
          "music_style": { "type": "string" },
          "duration_seconds": { "type": "number" },
          "reference_image_urls": { "type": "array", "items": { "type": "string", "format": "uri" } }
        }
      },
      "AudioResponse": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "model": { "type": "string" },
          "audio_kind": { "type": "string" },
          "audio_url": { "type": "string", "format": "uri" },
          "credits_charged": { "type": "integer" },
          "balance": { "$ref": "#/components/schemas/Balance" }
        }
      },
      "ModelsResponse": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string", "format": "uuid" },
          "org_id": { "type": "string", "format": "uuid" },
          "org_plan": { "type": "string" },
          "models": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "name": { "type": "string" },
                "type": { "type": "string" },
                "provider": { "type": "string" },
                "credits_per_request": { "type": "integer" }
              }
            }
          },
          "count": { "type": "integer" }
        }
      },
      "BalanceResponse": {
        "type": "object",
        "properties": {
          "org_id": { "type": "string", "format": "uuid" },
          "plan": { "type": "string" },
          "balance": {
            "type": "object",
            "properties": {
              "subscription_credits": { "type": "integer" },
              "anytime_credits": { "type": "integer" },
              "total_credits": { "type": "integer" },
              "subscription_credits_expire_at": { "type": "string", "format": "date-time" }
            }
          },
          "recent_ledger": { "type": "array", "items": { "type": "object" } }
        }
      },
      "UsageResponse": {
        "type": "object",
        "properties": {
          "summary": { "type": "object" },
          "by_api_key": { "type": "array", "items": { "type": "object" } },
          "by_member": { "type": "array", "items": { "type": "object" } },
          "requests": { "type": "array", "items": { "type": "object" } }
        }
      }
    }
  }
}
