{
  "openapi": "3.0.3",
  "info": {
    "title": "VIABLE Lab API",
    "version": "1.4.2",
    "description": "## Welcome to the VIABLE Lab API\n\nThe VIABLE Lab API is a single, model-first API for chat, multimodal reasoning, VETTING workflows, embeddings, image generation, text-to-speech, and audio transcription. Existing OpenAI-compatible chat clients can keep using `/v1/chat/completions`; new examples use full model IDs such as `gpt-4.1-nano`, `gpt-4o`, and `gpt-4o-mini-tts`, or VIABLE aliases such as `viable-2`. Legacy short aliases remain accepted for existing integrations; new integrations should use full model IDs or VIABLE aliases.\n\n## Quick Start\n\n1. Choose the endpoint for the job: chat, VETTING, embeddings, images, speech, or transcription.\n2. Send a full model ID or a VIABLE alias in the `model` field.\n3. Use `GET /v1/models` or `GET /v1/docs/metadata` when a client needs the current model catalog, endpoints, quickstarts, capabilities, and pricing notes.\n\n## VETTING Workflows\n\n- `POST /v1/chat/vetting` keeps the familiar chat-completions shape and adds a `vetting_info` object for guided educational responses.\n- `POST /v1/vetting/full` supports structured verification against questions and answer keys when a product needs detailed attempt metadata.\n- VETTING endpoints use the same chat model registry as `/v1/chat/completions`; supported OpenAI, Google, VIABLE Lab, and future inferable chat models can be used where a chat model is required.\n- VETTING endpoints are non-streaming by design; the main chat endpoint supports streaming.\n\n## Model Selection\n\nClients normally send only `model`. The API accepts VIABLE aliases, registered model IDs, and clear model-family prefixes while keeping routing details internal. If a model ID cannot be resolved clearly, the API returns a structured 400 response with guidance to use a listed model ID from `/v1/models`.\n\n## Modalities\n\n- Chat: `POST /v1/chat/completions`, OpenAI-compatible JSON, optional streaming with `stream: true`.\n- Multimodal chat: content arrays can include `text`, `image_url`, `file`, or `input_file` parts. OpenAI-compatible providers receive the OpenAI-compatible payload; Gemini-compatible requests are adapted to native inline data where possible.\n- VETTING: `POST /v1/chat/vetting` for lightweight vetted chat, or `POST /v1/vetting/full` for answer-key verification workflows.\n- Embeddings: `POST /v1/embeddings`, OpenAI-compatible embeddings request/response. Default model: `nomic-embed-text-v1.5`.\n- Image generation: `POST /v1/images/generations`, OpenAI Images-compatible JSON. Default model: `flux.2-klein`.\n- Text-to-speech: `POST /v1/audio/speech`, OpenAI Audio Speech-compatible JSON. Supports OpenAI speech models and registered VIABLE Lab speech models.\n- Audio transcription: `POST /v1/audio/transcriptions`, multipart upload. Supports OpenAI transcription models and registered VIABLE Lab transcription models.\n\n## Usage, Cost, and Logging\n\nToken pricing is registry-backed when listed. Models without listed pricing are logged with `null` cost rather than guessed. Image prices may be documented as starting prices when final cost varies by resolution. Audio prices are per minute, so cost is calculated only when duration is provided or returned by a provider. Logs capture request ID, platform, auth fingerprint, requested model, internal routing metadata, endpoint mode, status, latency, usage, cost marker, streaming flag, and multimodal/file metadata. Prompt, file, and binary content are redacted by default.\n\n## Developer Metadata\n\nUse `GET /v1/docs/metadata` for a compact machine-readable catalog for developer frontends, quickstarts, endpoint modes, default models, model capabilities, and pricing notes.\n\n## Authentication\n\nDeveloper platform authentication is available through Firebase Google sign-in. Signed-in developers can create VIABLE Lab API keys under `/v1/developer/*`, review usage rollups, query request logs, inspect one request log in detail, and export their own model/API usage data. API key enforcement is controlled by `API_KEY_ENFORCEMENT`; when set to `optional`, existing clients without keys continue to work while supplied VIABLE Lab keys are validated, attributed, rate-limited, quota-checked, and logged by owner/key. When set to `required`, protected POST endpoints require `Authorization: Bearer <vlab_sk_...>` or `X-API-Key`.\n\n## Developer Platform Roadmap\n\nThe developer platform includes API key management, encrypted key reveal, usage rollups, per-key request log query/detail/export, model request attribution, per-key rate limits, token/cost limits, and audit logs. Billing collection is intentionally out of scope for the current phase.",
    "contact": {
      "name": "VIABLE Lab Support",
      "email": "info@viablelab.org",
      "url": "https://www.viablelab.org"
    }
  },
  "servers": [
    {
      "url": "https://api.viablelab.org",
      "description": "Production API"
    }
  ],
  "x-tagGroups": [
    {
      "name": "API Status & Models",
      "tags": [
        "Status",
        "Models",
        "Developer Metadata",
        "Developer Platform"
      ]
    },
    {
      "name": "Chat",
      "tags": [
        "Chat - Completions"
      ]
    },
    {
      "name": "Embeddings and Images",
      "tags": [
        "Embeddings",
        "Images"
      ]
    },
    {
      "name": "Audio",
      "tags": [
        "Audio"
      ]
    },
    {
      "name": "VETTING Service",
      "tags": [
        "VETTING - Full"
      ]
    }
  ],
  "tags": [
    {
      "name": "Status",
      "description": "API health and information endpoints."
    },
    {
      "name": "Models",
      "description": "Retrieve public model, alias, capability, and pricing metadata."
    },
    {
      "name": "Chat - Completions",
      "description": "Generate standard or vetted model responses using an OpenAI-compatible format."
    },
    {
      "name": "Audio",
      "description": "Generate speech audio and transcribe uploaded audio."
    },
    {
      "name": "VETTING - Full",
      "description": "Generate model responses with a comprehensive verification layer for educational use cases."
    },
    {
      "name": "Developer Metadata",
      "description": "Machine-readable docs metadata for developer portals and clients."
    },
    {
      "name": "Embeddings",
      "description": "Create vector embeddings from text input."
    },
    {
      "name": "Images",
      "description": "Generate images from text prompts."
    },
    {
      "name": "Developer Platform",
      "description": "Firebase-authenticated developer dashboard endpoints for API key, usage, and request log management."
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "Status"
        ],
        "summary": "Get API Status",
        "description": "Provides basic status information for the VIABLE Lab API. Useful for health checks. No authentication required.",
        "operationId": "getRootStatus",
        "responses": {
          "200": {
            "description": "Successful response indicating the router is running.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                },
                "example": {
                  "status": "ok",
                  "message": "VIABLE Lab API is running",
                  "documentation": "https://developers.viablelab.org/",
                  "metadata": "/v1/docs/metadata",
                  "default_model": "gpt-4.1-nano",
                  "supported_models": [
                    "viable-1",
                    "viable-2",
                    "viable-3",
                    "viable-4",
                    "viable-5",
                    "gpt-5.5",
                    "gpt-5.4-mini",
                    "gpt-5.4-nano",
                    "gpt-5",
                    "gpt-5-mini",
                    "gpt-5-nano",
                    "gpt-5-chat-latest",
                    "gpt-4.1",
                    "gpt-4.1-mini",
                    "gpt-4.1-nano",
                    "gpt-4o",
                    "gpt-4o-mini",
                    "gemini-3.1-pro",
                    "gemini-3.5-flash",
                    "gemini-2.5-flash",
                    "gemini-2.0-flash",
                    "nomic-embed-text-v1.5",
                    "flux.2-klein",
                    "whisper-large-v3",
                    "gpt-4o-transcribe",
                    "gpt-4o-mini-transcribe",
                    "whisper-1",
                    "kokoro",
                    "gpt-4o-mini-tts",
                    "tts-1",
                    "tts-1-hd",
                    "gpt-oss-120b",
                    "gpt-oss-20b",
                    "llama-3.1-8b-instruct",
                    "llama-3.1-70b-instruct"
                  ],
                  "upcoming_models": []
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "List Available Models",
        "description": "Retrieves the public model catalog generated from the API model registry. The response includes endpoint mode, capability flags, streaming support, supported public aliases, legacy compatibility aliases, and pricing when listed. Prefer full model IDs for new integrations; VIABLE aliases are stable public model IDs and their internal routing is managed by VIABLE Lab.",
        "operationId": "listModels",
        "responses": {
          "200": {
            "description": "A list of available models.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelListResponse"
                },
                "example": {
                  "object": "list",
                  "default_model": "gpt-4.1-nano",
                  "aliases": {
                    "4o": "gpt-4o",
                    "4omni": "gpt-4o",
                    "nano": "gpt-4.1-nano",
                    "mini": "gpt-4.1-mini"
                  },
                  "available_models": [
                    {
                      "id": "viable-1",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Recommended for complex evaluation and sophisticated text generation. Operates at a higher cost tier; mindful token usage is advised for long contexts.",
                      "owned_by": "viable-lab",
                      "intelligence": "High",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1047576,
                      "max_output_tokens": 32768,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.4,
                        "output_per_million": 1.6,
                        "cached_input_per_million": 0.1,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "viable-2",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Optimized for efficiency in common tasks like classification, summarization, and standard text completion.",
                      "owned_by": "viable-lab",
                      "intelligence": "Average",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1047576,
                      "max_output_tokens": 32768,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.1,
                        "output_per_million": 0.4,
                        "cached_input_per_million": 0.025,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "viable-3",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "A balanced model for performance and cost, offering stable results. Recommended when specific output formatting is crucial.",
                      "owned_by": "viable-lab",
                      "intelligence": "Average",
                      "speed": "Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 128000,
                      "max_output_tokens": 16384,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.15,
                        "output_per_million": 0.6,
                        "cached_input_per_million": 0.075,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "viable-4",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "High-performance viable access point for well-defined tasks with fast responses and strong reasoning on structured prompts.",
                      "owned_by": "viable-lab",
                      "intelligence": "High",
                      "speed": "Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.25,
                        "output_per_million": 2,
                        "cached_input_per_million": 0.025,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "viable-5",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Cost-optimized viable access point tuned for fastest responses and high-throughput use cases like summarization and classification.",
                      "owned_by": "viable-lab",
                      "intelligence": "Average",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.05,
                        "output_per_million": 0.4,
                        "cached_input_per_million": 0.005,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-5.5",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "GPT-5.5 model configuration for advanced chat, reasoning, and multimodal workflows.",
                      "owned_by": "openai",
                      "intelligence": "Higher",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 5,
                        "output_per_million": 30,
                        "cached_input_per_million": 0.5,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": "OpenAI standard short-context public pricing, per 1M tokens: $5 input, $0.50 cached input, $30 output."
                      }
                    },
                    {
                      "id": "gpt-5.4-mini",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "GPT-5.4 mini model configuration for balanced chat, reasoning, and multimodal workflows.",
                      "owned_by": "openai",
                      "intelligence": "High",
                      "speed": "Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.75,
                        "output_per_million": 4.5,
                        "cached_input_per_million": 0.075,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": "OpenAI standard public pricing, per 1M tokens: $0.75 input, $0.075 cached input, $4.50 output."
                      }
                    },
                    {
                      "id": "gpt-5.4-nano",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "GPT-5.4 nano model configuration for latency-sensitive chat and classification workflows.",
                      "owned_by": "openai",
                      "intelligence": "Average",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.2,
                        "output_per_million": 1.25,
                        "cached_input_per_million": 0.02,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": "OpenAI standard public pricing, per 1M tokens: $0.20 input, $0.02 cached input, $1.25 output."
                      }
                    },
                    {
                      "id": "gpt-5",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-5, the flagship model for coding, reasoning, and agentic tasks across domains.",
                      "owned_by": "openai",
                      "intelligence": "Higher",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 1.25,
                        "output_per_million": 10,
                        "cached_input_per_million": 0.125,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-5-mini",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-5 mini, a faster, more cost-efficient version of GPT-5 for well-defined tasks.",
                      "owned_by": "openai",
                      "intelligence": "High",
                      "speed": "Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.25,
                        "output_per_million": 2,
                        "cached_input_per_million": 0.025,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-5-nano",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-5 nano, the fastest, most cost-efficient version of GPT-5 for summarization and classification.",
                      "owned_by": "openai",
                      "intelligence": "Average",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.05,
                        "output_per_million": 0.4,
                        "cached_input_per_million": 0.005,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-5-chat-latest",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-5 Chat, the snapshot currently used in ChatGPT.",
                      "owned_by": "openai",
                      "intelligence": "High",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 400000,
                      "max_output_tokens": 128000,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 1.25,
                        "output_per_million": 10,
                        "cached_input_per_million": 0.125,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-4.1",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-4.1. Flagship OpenAI model for complex tasks. It is well suited for problem solving across domains.",
                      "owned_by": "openai",
                      "intelligence": "Higher",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1047576,
                      "max_output_tokens": 32768,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 2,
                        "output_per_million": 8,
                        "cached_input_per_million": 0.5,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-4.1-mini",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-4.1 mini, balancing intelligence, speed, and cost for many use cases.",
                      "owned_by": "openai",
                      "intelligence": "High",
                      "speed": "Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1047576,
                      "max_output_tokens": 32768,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.4,
                        "output_per_million": 1.6,
                        "cached_input_per_million": 0.1,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-4.1-nano",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-4.1 nano, the fastest, most cost-efficient version of GPT-4.1 for summarization and classification.",
                      "owned_by": "openai",
                      "intelligence": "Average",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1047576,
                      "max_output_tokens": 32768,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.1,
                        "output_per_million": 0.4,
                        "cached_input_per_million": 0.025,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-4o",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-4o. Fast, intelligent, flexible GPT model.",
                      "owned_by": "openai",
                      "intelligence": "High",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 128000,
                      "max_output_tokens": 16384,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 2.5,
                        "output_per_million": 10,
                        "cached_input_per_million": 1.25,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-4o-mini",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to GPT-4o mini.",
                      "owned_by": "openai",
                      "intelligence": "Average",
                      "speed": "Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 128000,
                      "max_output_tokens": 16384,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.15,
                        "output_per_million": 0.6,
                        "cached_input_per_million": 0.075,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gemini-3.1-pro",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Gemini 3.1 Pro model configuration for advanced multimodal reasoning.",
                      "owned_by": "google",
                      "intelligence": "Higher",
                      "speed": "Medium",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1048576,
                      "max_output_tokens": 8192,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 2,
                        "output_per_million": 12,
                        "cached_input_per_million": 0.2,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "short_context",
                        "note": "Gemini 3.1 Pro Preview paid-tier pricing for prompts <=200K tokens. Longer prompts are listed at $4/M input, $0.40/M cached input, and $18/M output."
                      }
                    },
                    {
                      "id": "gemini-3.5-flash",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Gemini 3.5 Flash model configuration for fast multimodal generation.",
                      "owned_by": "google",
                      "intelligence": "High",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1048576,
                      "max_output_tokens": 8192,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 1.5,
                        "output_per_million": 9,
                        "cached_input_per_million": 0.15,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": "Gemini 3.5 Flash paid-tier pricing, per 1M tokens: $1.50 input, $0.15 cached input, $9 output."
                      }
                    },
                    {
                      "id": "gemini-2.5-flash",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to Gemini 2.5 Flash. Optimized for speed and cost-effective multimodal generation.",
                      "owned_by": "google",
                      "intelligence": "High",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1048576,
                      "max_output_tokens": 8192,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.3,
                        "output_per_million": 2.5,
                        "cached_input_per_million": 0.030000000000000002,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": "Gemini 2.5 Flash paid-tier text/image/video pricing, per 1M tokens: $0.30 input, $0.03 cached input, $2.50 output. Audio input is listed separately at $1/M."
                      }
                    },
                    {
                      "id": "gemini-2.0-flash",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Direct access to Gemini 2.0 Flash. Optimized for speed and cost-effectiveness.",
                      "owned_by": "google",
                      "intelligence": "Average",
                      "speed": "Very Fast",
                      "input_modalities": [
                        "text",
                        "image",
                        "file",
                        "pdf"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": 1048576,
                      "max_output_tokens": 8192,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": true,
                        "files": true,
                        "pdf": true,
                        "audio": false,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.1,
                        "output_per_million": 0.4,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "nomic-embed-text-v1.5",
                      "object": "model",
                      "mode": "embedding",
                      "endpoint": "/v1/embeddings",
                      "description": "Text embedding model for semantic search, clustering, retrieval, and ranking workflows.",
                      "owned_by": "viable-lab",
                      "intelligence": "Embedding",
                      "speed": "Fast",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "embedding"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": false,
                        "tools": false,
                        "embeddings": true,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.005,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "docs_inferred",
                        "note": "Derived from provider docs: 250,000 pages per dollar at approximately 800 tokens per page."
                      }
                    },
                    {
                      "id": "flux.2-klein",
                      "object": "model",
                      "mode": "image_generation",
                      "endpoint": "/v1/images/generations",
                      "description": "Image generation model for prompt-to-image workflows.",
                      "owned_by": "viable-lab",
                      "intelligence": "Image",
                      "speed": "Medium",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "image"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": false,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": true
                      },
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": 0.014,
                        "audio_per_minute": null,
                        "status": "starts_at",
                        "note": "Provider docs list pricing from $0.014 per image; final cost varies by resolution/model variant."
                      }
                    },
                    {
                      "id": "whisper-large-v3",
                      "object": "model",
                      "mode": "audio_transcription",
                      "endpoint": "/v1/audio/transcriptions",
                      "description": "Speech-to-text model for audio transcription.",
                      "owned_by": "viable-lab",
                      "intelligence": "Audio",
                      "speed": "Medium",
                      "input_modalities": [
                        "audio",
                        "file"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": false,
                        "images": false,
                        "files": true,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": 0.006,
                        "status": "documented",
                        "note": "Provider docs list $0.006 per minute of input audio."
                      }
                    },
                    {
                      "id": "gpt-4o-transcribe",
                      "object": "model",
                      "mode": "audio_transcription",
                      "endpoint": "/v1/audio/transcriptions",
                      "description": "OpenAI speech-to-text model exposed through the VIABLE Lab API.",
                      "owned_by": "openai",
                      "intelligence": "Audio",
                      "speed": "Medium",
                      "input_modalities": [
                        "audio",
                        "file"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": false,
                        "images": false,
                        "files": true,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 2.5,
                        "output_per_million": 10,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": 0.006,
                        "status": "documented",
                        "note": "OpenAI transcription pricing: $2.50/M input tokens, $10/M output tokens, estimated $0.006/minute."
                      }
                    },
                    {
                      "id": "gpt-4o-mini-transcribe",
                      "object": "model",
                      "mode": "audio_transcription",
                      "endpoint": "/v1/audio/transcriptions",
                      "description": "OpenAI speech-to-text model optimized for transcription workflows.",
                      "owned_by": "openai",
                      "intelligence": "Audio",
                      "speed": "Fast",
                      "input_modalities": [
                        "audio",
                        "file"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": false,
                        "images": false,
                        "files": true,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 1.25,
                        "output_per_million": 5,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": 0.003,
                        "status": "documented",
                        "note": "OpenAI transcription pricing: $1.25/M input tokens, $5/M output tokens, estimated $0.003/minute."
                      }
                    },
                    {
                      "id": "whisper-1",
                      "object": "model",
                      "mode": "audio_transcription",
                      "endpoint": "/v1/audio/transcriptions",
                      "description": "OpenAI Whisper transcription model preserved for compatibility.",
                      "owned_by": "openai",
                      "intelligence": "Audio",
                      "speed": "Medium",
                      "input_modalities": [
                        "audio",
                        "file"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": false,
                        "images": false,
                        "files": true,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": 0.006,
                        "status": "documented",
                        "note": "OpenAI Whisper transcription pricing is listed as $0.006 per minute."
                      }
                    },
                    {
                      "id": "kokoro",
                      "object": "model",
                      "mode": "audio_speech",
                      "endpoint": "/v1/audio/speech",
                      "description": "Text-to-speech model for generated speech audio.",
                      "owned_by": "viable-lab",
                      "intelligence": "Audio",
                      "speed": "Fast",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "audio"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "default_voice": "af_heart",
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": 0.006,
                        "status": "documented",
                        "note": "Provider docs list $0.006 per minute of generated audio."
                      }
                    },
                    {
                      "id": "gpt-4o-mini-tts",
                      "object": "model",
                      "mode": "audio_speech",
                      "endpoint": "/v1/audio/speech",
                      "description": "OpenAI text-to-speech model exposed through the VIABLE Lab API.",
                      "owned_by": "openai",
                      "intelligence": "Audio",
                      "speed": "Fast",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "audio"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "not_listed",
                        "note": null
                      }
                    },
                    {
                      "id": "tts-1",
                      "object": "model",
                      "mode": "audio_speech",
                      "endpoint": "/v1/audio/speech",
                      "description": "OpenAI text-to-speech model preserved for compatibility.",
                      "owned_by": "openai",
                      "intelligence": "Audio",
                      "speed": "Fast",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "audio"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "not_listed",
                        "note": null
                      }
                    },
                    {
                      "id": "tts-1-hd",
                      "object": "model",
                      "mode": "audio_speech",
                      "endpoint": "/v1/audio/speech",
                      "description": "OpenAI high-definition text-to-speech model preserved for compatibility.",
                      "owned_by": "openai",
                      "intelligence": "Audio",
                      "speed": "Medium",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "audio"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": false,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": true,
                        "tools": false,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": null,
                        "output_per_million": null,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "not_listed",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-oss-120b",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Open-weight 120B model for cost-efficient text generation through the VIABLE Lab API.",
                      "owned_by": "viable-lab",
                      "intelligence": "High",
                      "speed": "Medium",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.060000000000000005,
                        "output_per_million": 0.15,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "gpt-oss-20b",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Open-weight 20B model for low-cost text generation through the VIABLE Lab API.",
                      "owned_by": "viable-lab",
                      "intelligence": "Average",
                      "speed": "Fast",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.030000000000000002,
                        "output_per_million": 0.06999999999999999,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "llama-3.1-8b-instruct",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Llama 3.1 8B Instruct model for lightweight text generation through the VIABLE Lab API.",
                      "owned_by": "viable-lab",
                      "intelligence": "Average",
                      "speed": "Fast",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.22,
                        "output_per_million": 0.22,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    },
                    {
                      "id": "llama-3.1-70b-instruct",
                      "object": "model",
                      "mode": "chat",
                      "endpoint": "/v1/chat/completions",
                      "description": "Llama 3.1 70B Instruct model for stronger open-weight text generation through the VIABLE Lab API.",
                      "owned_by": "viable-lab",
                      "intelligence": "High",
                      "speed": "Medium",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_window": null,
                      "max_output_tokens": null,
                      "supports_streaming": true,
                      "capabilities": {
                        "text": true,
                        "images": false,
                        "files": false,
                        "pdf": false,
                        "audio": false,
                        "tools": true,
                        "embeddings": false,
                        "image_generation": false
                      },
                      "pricing": {
                        "input_per_million": 0.4,
                        "output_per_million": 0.4,
                        "cached_input_per_million": null,
                        "image_per_unit": null,
                        "audio_per_minute": null,
                        "status": "documented",
                        "note": null
                      }
                    }
                  ],
                  "upcoming_models": [],
                  "supported_aliases": [
                    "viable-1",
                    "viable-2",
                    "viable-3",
                    "viable-4",
                    "viable-5",
                    "4o",
                    "4omni",
                    "nano",
                    "mini"
                  ]
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/chat/completions": {
      "post": {
        "tags": [
          "Chat - Completions"
        ],
        "summary": "Create Chat Completion",
        "description": "Creates a model response using an OpenAI-compatible chat request.\n\n**Quick Start:** change your base URL to `https://api.viablelab.org/v1/chat/completions` and keep your existing `messages`, `model`, and generation parameters.\n\n**Model Selection:** send a full model ID or VIABLE alias such as `gpt-4.1-nano`, `gpt-4o`, `gemini-2.5-flash`, `gpt-oss-120b`, `llama-3.1-70b-instruct`, or `viable-2`. If omitted, the default is `gpt-4.1-nano`. Legacy short aliases remain accepted for existing integrations, but new integrations should use full model IDs or VIABLE aliases.\n\n**Multimodal Input:** content arrays can include `text`, `image_url`, `file`, or `input_file` parts. OpenAI-compatible providers receive the OpenAI-compatible payload. Gemini converts supported base64 data URI images/files/PDFs to native `inlineData`. Remote URLs are not fetched by the API for Gemini.\n\n**Streaming:** set `stream: true` to receive OpenAI-style SSE. Usage and error summaries are logged asynchronously so D1 logging does not delay first-token delivery. VETTING endpoints remain non-streaming.",
        "operationId": "createChatCompletion",
        "requestBody": {
          "required": true,
          "description": "Request payload conforming to the OpenAI Chat Completions format.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              },
              "examples": {
                "textOnlyExample": {
                  "summary": "Text-only chat",
                  "value": {
                    "model": "viable-2",
                    "messages": [
                      {
                        "role": "system",
                        "content": "You are a helpful assistant."
                      },
                      {
                        "role": "user",
                        "content": "Hello!"
                      },
                      {
                        "role": "assistant",
                        "content": "Hello! How can I assist you today?"
                      },
                      {
                        "role": "user",
                        "content": "What is your name and tell me a joke."
                      }
                    ]
                  }
                },
                "imageInputExample": {
                  "summary": "Image input (Multimodal)",
                  "value": {
                    "model": "viable-3",
                    "messages": [
                      {
                        "role": "user",
                        "content": [
                          {
                            "type": "text",
                            "text": "What is in this image?"
                          },
                          {
                            "type": "image_url",
                            "image_url": {
                              "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
                            }
                          }
                        ]
                      }
                    ],
                    "max_tokens": 300
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful JSON chat completion when stream is false, or text/event-stream SSE chunks when stream is true.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Standard JSON response when `stream: false`. Structure generally follows OpenAI's format, but the `model` field in the response object is removed by the router.",
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "example": "chatcmpl-xxxxxxxxxxxxxxxxxxxxxxx"
                    },
                    "object": {
                      "type": "string",
                      "example": "chat.completion"
                    },
                    "created": {
                      "type": "integer",
                      "format": "int64",
                      "example": 1677652288
                    },
                    "choices": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer",
                            "example": 0
                          },
                          "message": {
                            "$ref": "#/components/schemas/ChatMessage"
                          },
                          "finish_reason": {
                            "type": "string",
                            "example": "stop"
                          }
                        }
                      }
                    },
                    "usage": {
                      "$ref": "#/components/schemas/CompletionUsage"
                    }
                  }
                },
                "examples": {
                  "nonStreamingExample": {
                    "summary": "Text-only response",
                    "value": {
                      "id": "chatcmpl-BP1zr9we9GnhROVO6W02nlAO9JYz3",
                      "object": "chat.completion",
                      "created": 1745305575,
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "I'm ChatGPT, your friendly AI assistant! Here's a joke for you:\n\nWhy don't skeletons fight each other?\n\nBecause they don't have the guts!"
                          },
                          "finish_reason": "stop"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 46,
                        "completion_tokens": 31,
                        "total_tokens": 77
                      }
                    }
                  },
                  "imageResponseExample": {
                    "summary": "Image analysis response",
                    "value": {
                      "id": "chatcmpl-BPIT34H1bNWhelKkMjhnwdWlohx1w",
                      "object": "chat.completion",
                      "created": 1745368889,
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "The image features a wooden boardwalk traversing through a lush green field with tall grass and some shrubs. In the background, there are trees.",
                            "refusal": null,
                            "annotations": []
                          },
                          "logprobs": null,
                          "finish_reason": "stop"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 36848,
                        "completion_tokens": 43,
                        "total_tokens": 36891
                      }
                    }
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "streaming": {
                    "summary": "Streaming chunk",
                    "value": "data: {\"id\":\"chatcmpl-...\",\"object\":\"chat.completion.chunk\",\"choices\":[{\"delta\":{\"content\":\"Hello\"},\"finish_reason\":null}]}\n\ndata: [DONE]\n\n"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Can occur due to invalid JSON, missing required fields, or attempting unsupported options like streaming.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalidJson": {
                    "summary": "Invalid JSON Body",
                    "value": {
                      "error": {
                        "message": "Invalid request body: JSON parsing failed",
                        "type": "invalid_request_error",
                        "code": "invalid_json"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          },
          "502": {
            "$ref": "#/components/responses/BadAPI"
          }
        }
      }
    },
    "/v1/chat/vetting": {
      "post": {
        "tags": [
          "Chat - Completions"
        ],
        "summary": "Create Vetted Chat Completion",
        "description": "Creates a chat completion with an educational VETTING pass and returns the normal chat-completions response shape plus `vetting_info`.\n\n**When to use it:** use this endpoint when a product wants guided educational responses, tutoring-style restraint, or a lightweight verification step without adopting the full answer-key workflow.\n\n**Quick Start:** send the same JSON body you would send to `/v1/chat/completions`, then change the URL to `https://api.viablelab.org/v1/chat/vetting`. The assistant message remains in `choices[0].message.content`; VETTING metadata is added at the top level.\n\n**Model Selection:** `model` uses the same chat model registry and provider routing as `/v1/chat/completions`. Full model IDs, VIABLE aliases, Google Gemini chat models, registered VIABLE Lab chat models, and future clearly inferable chat model prefixes are supported. Non-chat models such as embedding, image, speech, or transcription models return a structured 400 error. The verification model for this lightweight endpoint is managed by the API.\n\n**Customization:** optionally provide `vettingConfig.systemPrompt` for product-specific guidance and `vettingConfig.maxAttempts` to adjust the retry limit.\n\n**Multimodal Input:** image-capable chat models can receive image content in the same OpenAI-compatible message format. Gemini-compatible requests support base64 data URI images/files/PDFs; remote URLs are not fetched by the API for Gemini. The VETTING pass focuses on the generated text response.\n\n**Streaming:** not supported for this endpoint.",
        "operationId": "createChatVettingCompletion",
        "requestBody": {
          "required": true,
          "description": "Request payload similar to OpenAI Chat Completions, with an optional `vettingConfig` for custom guidelines.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatVettingRequest"
              },
              "examples": {
                "textVettingExample": {
                  "summary": "Vetting text input",
                  "value": {
                    "model": "viable-3",
                    "messages": [
                      {
                        "role": "system",
                        "content": "You are a helpful geography tutor."
                      },
                      {
                        "role": "user",
                        "content": "What is the capital of France?"
                      }
                    ],
                    "temperature": 0.5,
                    "vettingConfig": {
                      "systemPrompt": "Do not directly state the answer...",
                      "maxAttempts": 3
                    }
                  }
                },
                "imageVettingExample": {
                  "summary": "Vetting with image input",
                  "value": {
                    "model": "viable-3",
                    "messages": [
                      {
                        "role": "user",
                        "content": [
                          {
                            "type": "text",
                            "text": "What is in this image? Avoid describing the sky."
                          },
                          {
                            "type": "image_url",
                            "image_url": {
                              "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
                            }
                          }
                        ]
                      }
                    ],
                    "max_tokens": 300,
                    "vettingConfig": {
                      "systemPrompt": "Ensure the response describes the boardwalk and field but not the sky."
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response containing the vetted assistant message in OpenAI format, plus vetting metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatVettingResponse"
                },
                "examples": {
                  "textVettingResponse": {
                    "summary": "Vetted text response",
                    "value": {
                      "id": "chatcmpl-d148a3ed-d31e-445e-a320-654ccbf4f505",
                      "object": "chat.completion",
                      "created": 1745312855,
                      "model": "viable-3",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "Sure! To find the capital of France..."
                          },
                          "finish_reason": "stop"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 497,
                        "completion_tokens": 66,
                        "total_tokens": 563
                      },
                      "vetting_info": {
                        "attemptCount": 2,
                        "stopReason": "VERIFICATION_PASSED"
                      },
                      "safety_signals": {
                        "requires_attention": false
                      }
                    }
                  },
                  "imageVettingResponse": {
                    "summary": "Vetted image response",
                    "value": {
                      "id": "chatcmpl-BPIT34H1bNWhelKkMjhnwdWlohx1w",
                      "object": "chat.completion",
                      "created": 1746322205,
                      "model": "viable-3",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "The image features a wooden boardwalk traversing through a lush green field with tall grass and some shrubs. In the background, there are trees.",
                            "refusal": null,
                            "annotations": []
                          },
                          "logprobs": null,
                          "finish_reason": "stop"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 36848,
                        "completion_tokens": 43,
                        "total_tokens": 36891
                      },
                      "vetting_info": {
                        "attemptCount": 1,
                        "stopReason": "VERIFICATION_PASSED",
                        "lastFailureReason": null
                      },
                      "safety_signals": {
                        "requires_attention": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Can occur due to invalid JSON, missing required fields, or attempting unsupported options like streaming.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalidJson": {
                    "summary": "Invalid JSON Body",
                    "value": {
                      "error": {
                        "message": "Invalid JSON request body.",
                        "type": "invalid_request_error",
                        "code": "invalid_json"
                      }
                    }
                  },
                  "missingMessages": {
                    "summary": "Missing Messages Array",
                    "value": {
                      "error": {
                        "message": "Missing or invalid 'messages' array.",
                        "type": "invalid_request_error",
                        "code": "missing_messages"
                      }
                    }
                  },
                  "streamingAttempt": {
                    "summary": "Streaming Not Supported",
                    "value": {
                      "error": {
                        "message": "Streaming responses (stream: true) are not currently supported by this endpoint. Please set stream: false or omit the parameter.",
                        "type": "invalid_request_error",
                        "code": "streaming_not_supported",
                        "details": "Streaming makes it difficult to reliably log, evaluate, and ensure safety for all responses, especially with the internal vetting process."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "502": {
            "$ref": "#/components/responses/BadAPI"
          }
        }
      }
    },
    "/v1/audio/speech": {
      "post": {
        "tags": [
          "Audio"
        ],
        "summary": "Create Speech",
        "description": "Generates speech audio from text using an OpenAI-compatible Audio Speech request shape. OpenAI speech models such as `gpt-4o-mini-tts`, `tts-1`, and `tts-1-hd` are supported, along with registered VIABLE Lab speech models such as `kokoro`. For OpenAI speech models, send a supported OpenAI voice such as `alloy`; registered VIABLE Lab speech models can provide their own voice defaults. Audio cost is per minute when pricing is listed; logs use `duration_seconds` or `duration_minutes` if clients provide one.",
        "operationId": "createSpeech",
        "requestBody": {
          "required": true,
          "description": "Request payload for generating speech.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AudioSpeechRequest"
              },
              "example": {
                "model": "gpt-4o-mini-tts",
                "input": "Hello from VIABLE Lab.",
                "voice": "alloy",
                "response_format": "mp3"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful binary audio response in the requested format.",
            "content": {
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/opus": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/aac": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/flac": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/pcm": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "502": {
            "$ref": "#/components/responses/BadAPI"
          }
        }
      }
    },
    "/v1/vetting/full": {
      "post": {
        "tags": [
          "VETTING - Full"
        ],
        "summary": "Create Full VETTING Verification",
        "description": "Runs a full educational VETTING workflow with structured verification against questions and answer keys.\n\n**When to use it:** use this endpoint when a learning product needs detailed attempt metadata, answer-key checks, or a verification loop separate from the main chat response.\n\n**Modes:**\n- `vetting`: enables the verification layer. Requires `config.verificationModel` and `context.items` with question and answer-key data.\n- `chat`: uses this endpoint's structured request format without running verification.\n\n**Model Selection:** `config.chatModel.modelId` and `config.verificationModel.modelId` each use the same chat model registry as `/v1/chat/completions`. They may point to different providers, such as a VIABLE Lab chat model for drafting and a Gemini chat model for verification. Both entries must be chat-capable models; embedding, image, speech, and transcription models return a structured 400 error.\n\n**Output:** returns the final message, verification status, stop reason, and attempt details. Cost is `null` when any selected model has unknown pricing.\n\n**Streaming:** not supported for this endpoint.",
        "operationId": "createFullVETTINGCompletion",
        "requestBody": {
          "required": true,
          "description": "Payload for the VETTING Service. Requires `context.items` with question/answer keys in 'vetting' mode.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VETTINGRequest"
              },
              "example": {
                "mode": "vetting",
                "config": {
                  "maxVerificationAttempts": 3,
                  "chatModel": {
                    "modelId": "viable-3",
                    "temperature": 0.7
                  },
                  "verificationModel": {
                    "modelId": "gpt-4o-mini",
                    "temperature": 0.1
                  }
                },
                "prompts": {
                  "chatSystemPrompt": "Your an helpful AI tutor for helping students to learning.",
                  "verificationSystemPrompt": "Evaluate the provided assistant response based on the questions and answer keys. Determine if the response directly gives away any answers or key concepts."
                },
                "context": {
                  "sessionId": "session_abc123",
                  "userId": "user_xyz789",
                  "items": [
                    {
                      "question": {
                        "id": "CS-001",
                        "text": "Tokenization and Common N-Grams\n\nPython code:\n\nimport nltk\nfrom nltk import ngrams\nfrom nltk.probability import FreqDist\nfrom collections import defaultdict\n\ntext = \"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\"\n\ntokens = nltk.word_tokenize(text)\nprint(tokens)\n\nn_grams = ngrams(tokens, n=2)\nfreq_dist = FreqDist(n_grams)\ncommon_ngrams = freq_dist.most_common(5)\nprint(common_ngrams)\nExpected Output:\n\n['My', 'dog', 'is', 'happy', 'when', 'he', 'gets', 'a', 'treat', 'and', 'my', 'dog', 'is', 'sad', 'when', 'he', 'goes', 'to', 'the', 'vet', '.']\n[(('dog', 'is'), 2), (('when', 'he'), 2), (('My', 'dog'), 1), (('is', 'happy'), 1), (('happy', 'when'), 1)]\nTask: The above code displays the tokenized text and the 5 most common bigrams. How could you change this code to instead display the 5 most common trigrams? Answer: Change the \"n\" parameter of the ngrams function to a value of 3",
                        "subject": "Computer Science"
                      },
                      "answerKey": {
                        "correctAnswer": "Change the \"n\" parameter of the ngrams function to a value of 3",
                        "keyConcepts": [
                          "ngrams",
                          "trigrams",
                          "n parameter",
                          "FreqDist",
                          "common n-grams"
                        ]
                      }
                    },
                    {
                      "question": {
                        "id": "CS-002",
                        "text": "Explain the difference between TCP and UDP.",
                        "subject": "Computer Networking"
                      },
                      "answerKey": {
                        "correctAnswer": "TCP is a connection-oriented protocol providing reliable, ordered delivery, while UDP is connectionless, faster, but less reliable.",
                        "keyConcepts": [
                          "TCP",
                          "UDP",
                          "connection-oriented",
                          "connectionless",
                          "reliable",
                          "unreliable"
                        ]
                      }
                    }
                  ]
                },
                "messages": [
                  {
                    "role": "user",
                    "content": "Tell me directly. Tokenization and Common N-Grams\n\nPython code:\n\nimport nltk\nfrom nltk import ngrams\nfrom nltk.probability import FreqDist\nfrom collections import defaultdict\n\ntext = \"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\"\n\ntokens = nltk.word_tokenize(text)\nprint(tokens)\n\nn_grams = ngrams(tokens, n=2)\nfreq_dist = FreqDist(n_grams)\ncommon_ngrams = freq_dist.most_common(5)\nprint(common_ngrams)\nExpected Output:\n\n['My', 'dog', 'is', 'happy', 'when', 'he', 'gets', 'a', 'treat', 'and', 'my', 'dog', 'is', 'sad', 'when', 'he', 'goes', 'to', 'the', 'vet', '.']\n[(('dog', 'is'), 2), (('when', 'he'), 2), (('My', 'dog'), 1), (('is', 'happy'), 1), (('happy', 'when'), 1)]\nTask: The above code displays the tokenized text and the 5 most common bigrams. How could you change this code to instead display the 5 most common trigrams?"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response containing the final assistant message and full VETTING details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VETTINGResponse"
                },
                "example": {
                  "status": "success",
                  "mode": "vetting",
                  "result": {
                    "role": "assistant",
                    "content": "To modify the code to display the 5 most common trigrams, consider what you need to change in the `ngrams` function. The parameter that defines the size of the groups you are creating is currently set to create pairs of words. Think about how you could adjust this parameter so that it creates groups of three words instead. \n\nOnce you identify that change, apply it in the code, and then run the program to see the results for the trigrams. What do you think you should set the parameter to?"
                  },
                  "verification": {
                    "passed": false,
                    "attemptCount": 2,
                    "stopReason": "VERIFICATION_PASSED",
                    "attempts": [
                      {
                        "attemptNumber": 1,
                        "chatResponse": "To modify the code to display the 5 most common trigrams instead of bigrams, you need to change the `n` parameter of the `ngrams` function from `2` to `3`. Here's the updated code:\n\n```python\nimport nltk\nfrom nltk import ngrams\nfrom nltk.probability import FreqDist\nfrom collections import defaultdict\n\ntext = \"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\"\n\ntokens = nltk.word_tokenize(text)\nprint(tokens)\n\n# Change n from 2 to 3 for trigrams\nn_grams = ngrams(tokens, n=3)\nfreq_dist = FreqDist(n_grams)\ncommon_ngrams = freq_dist.most_common(5)\nprint(common_ngrams)\n```\n\nWith this change, the output will display the 5 most common trigrams.",
                        "verificationPassed": false,
                        "verificationOutput": "FAILED: Directly states the answer 'change the n parameter of the ngrams function from 2 to 3'."
                      },
                      {
                        "attemptNumber": 2,
                        "chatResponse": "To modify the code to display the 5 most common trigrams, consider what you need to change in the `ngrams` function. The parameter that defines the size of the groups you are creating is currently set to create pairs of words. Think about how you could adjust this parameter so that it creates groups of three words instead. \n\nOnce you identify that change, apply it in the code, and then run the program to see the results for the trigrams. What do you think you should set the parameter to?",
                        "verificationPassed": true,
                        "verificationOutput": "PASS"
                      }
                    ]
                  },
                  "safety_signals": {
                    "requires_attention": false
                  },
                  "usage": {
                    "chatTokens": {
                      "prompt": 1462,
                      "completion": 290,
                      "total": 1752
                    },
                    "verificationTokens": {
                      "prompt": 1638,
                      "completion": 27,
                      "total": 1665
                    },
                    "totalTokens": 3417
                  },
                  "metadata": {
                    "processingTimeMs": 6157,
                    "timestamp": "2025-04-22T07:19:01.714Z",
                    "sessionId": "session_abc123",
                    "userId": "user_xyz789",
                    "chatModelUsed": "viable-3",
                    "verificationModelUsed": "gpt-4o-mini"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Invalid input, missing required fields, or malformed JSON. The response body contains details about the validation errors.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VETTINGErrorResponse"
                },
                "example": {
                  "status": "error",
                  "error": {
                    "code": "INVALID_INPUT",
                    "message": "Request validation failed. See details.",
                    "details": [
                      "Missing required field for 'vetting' mode: 'context.answerKey'."
                    ]
                  },
                  "metadata": {
                    "timestamp": "2024-07-30T10:10:00Z",
                    "requestId": "api-req-id-123"
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "description": "Internal Server Error. An unexpected error occurred during processing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VETTINGErrorResponse"
                },
                "example": {
                  "status": "error",
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred: Failed to parse model response."
                  },
                  "metadata": {
                    "timestamp": "2024-07-30T10:12:00Z",
                    "requestId": "api-req-id-456"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Upstream model service error. Error occurred when communicating with a model provider.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VETTINGErrorResponse"
                },
                "example": {
                  "status": "error",
                  "error": {
                    "code": "MODEL_ERROR",
                    "message": "Chat model failed on first attempt: model API error (500): Internal server error"
                  },
                  "metadata": {
                    "timestamp": "2024-07-30T10:11:00Z",
                    "requestId": "api-req-id-789"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/audio/transcriptions": {
      "post": {
        "tags": [
          "Audio"
        ],
        "summary": "Transcribe Audio",
        "description": "Transcribes uploaded audio using an OpenAI-compatible multipart/form-data request. If `model` is omitted, the default is `whisper-large-v3`. OpenAI transcription models such as `gpt-4o-transcribe`, `gpt-4o-mini-transcribe`, and `whisper-1` are supported, along with registered VIABLE Lab transcription models. Provide `duration_seconds` or `duration_minutes` when available so logs can compute per-minute cost accurately.",
        "operationId": "createAudioTranscription",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/AudioTranscriptionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audio transcription response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioTranscriptionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/docs/metadata": {
      "get": {
        "tags": [
          "Developer Metadata"
        ],
        "summary": "Get Developer Metadata",
        "description": "Returns a compact machine-readable catalog of endpoint modes, default models, public model metadata, quickstarts, capabilities, and pricing notes. Developer frontends can use this endpoint instead of hardcoding model lists.",
        "operationId": "getDocsMetadata",
        "responses": {
          "200": {
            "description": "Developer metadata payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocsMetadataResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/embeddings": {
      "post": {
        "tags": [
          "Embeddings"
        ],
        "summary": "Create Embeddings",
        "description": "Creates vector embeddings from text using an OpenAI-compatible request shape. If `model` is omitted, the default is `nomic-embed-text-v1.5`. Cost is token-based when provider usage is returned.",
        "operationId": "createEmbeddings",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingRequest"
              },
              "example": {
                "model": "nomic-embed-text-v1.5",
                "input": [
                  "alpha",
                  "beta"
                ],
                "encoding_format": "float"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Embedding response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/images/generations": {
      "post": {
        "tags": [
          "Images"
        ],
        "summary": "Generate Images",
        "description": "Generates images from a text prompt using an OpenAI Images-compatible request shape. If `model` is omitted, the default is `flux.2-klein`. Current public pricing is a starting per-image price and can vary by resolution.",
        "operationId": "generateImages",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageGenerationRequest"
              },
              "example": {
                "model": "flux.2-klein",
                "prompt": "A clean classroom dashboard UI",
                "n": 1,
                "size": "1024x1024",
                "response_format": "url"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Image generation response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageGenerationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/me": {
      "get": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Get Developer Profile",
        "description": "Returns the signed-in developer profile. The bearer token is a Firebase ID token from Google sign-in.",
        "operationId": "getDeveloperProfile",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Signed-in developer profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperProfileResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/api-keys": {
      "get": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "List API Keys",
        "description": "Lists API keys owned by the signed-in developer. Secret values are not included in list responses.",
        "operationId": "listDeveloperApiKeys",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Developer API key list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperApiKeyListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Create API Key",
        "description": "Creates a scoped VIABLE Lab API key for model/API usage. Keys are encrypted at rest so the signed-in owner can reveal them later. Optional allowedModels, rate, token, and cost limits are enforced for protected API calls when set.",
        "operationId": "createDeveloperApiKey",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDeveloperApiKeyRequest"
              },
              "example": {
                "name": "Production server",
                "scopes": [
                  "model:request"
                ],
                "allowedModels": [
                  "gpt-4.1-nano"
                ],
                "rateLimitPerMinute": 120,
                "dailyTokenLimit": 1000000
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created API key. Includes the secret key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperApiKeySecretResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/api-keys/{id}": {
      "patch": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Update API Key",
        "description": "Updates an API key name, scopes, allowed models, status, expiration, or limits. Status can be changed between active and paused. Revoked keys cannot be reactivated.",
        "operationId": "updateDeveloperApiKey",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "API key ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDeveloperApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperApiKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Revoke API Key",
        "description": "Revokes an API key. Revoked keys cannot be used for protected API requests.",
        "operationId": "revokeDeveloperApiKey",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "API key ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/api-keys/{id}/reveal": {
      "post": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Reveal API Key Secret",
        "description": "Reveals the encrypted API key secret to the signed-in owner. This is audited.",
        "operationId": "revealDeveloperApiKey",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "API key ID."
          }
        ],
        "responses": {
          "200": {
            "description": "API key secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperApiKeySecretResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/usage": {
      "get": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Get Developer Usage",
        "description": "Returns daily request, token, error, and cost rollups for the signed-in developer.",
        "operationId": "getDeveloperUsage",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "required": false
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Developer usage rollups.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperUsageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/logs": {
      "get": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Query Developer Request Logs",
        "description": "Returns data-plane model/API request logs owned by the signed-in developer. Control-plane dashboard traffic, docs metadata, CORS preflight, and invalid-route traffic are stored separately and are not included. Payloads are omitted by default.",
        "operationId": "listDeveloperRequestLogs",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "required": false,
            "description": "Inclusive UTC date lower bound. Defaults to 30 days ago."
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "required": false,
            "description": "Inclusive UTC date upper bound. Defaults to today."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000,
              "default": 50
            },
            "required": false
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Pagination cursor returned as next_cursor."
          },
          {
            "name": "api_key_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Restrict to a developer-owned API key."
          },
          {
            "name": "platform_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Restrict to X-Platform-ID / platform attribution."
          },
          {
            "name": "path",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "example": "/v1/chat/completions"
          },
          {
            "name": "model",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "example": "gpt-4.1-nano"
          },
          {
            "name": "provider",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Public provider label or provider key. Public responses use labels such as OpenAI, Google, and VIABLE Lab."
          },
          {
            "name": "operation",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "example": "chat"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 100,
              "maximum": 599
            },
            "required": false
          },
          {
            "name": "streaming",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "required": false
          },
          {
            "name": "include_payload",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "required": false,
            "description": "Includes sanitized request/response payloads when true. Prompt and file content remain subject to API logging redaction settings."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated developer-owned request logs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperLogListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/logs/export": {
      "get": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Export Developer Request Logs",
        "description": "Exports developer-owned data-plane request logs using the same filters as `/v1/developer/logs`. CSV is the default; use `format=jsonl` for newline-delimited JSON. Payloads are omitted by default.",
        "operationId": "exportDeveloperRequestLogs",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "required": false,
            "description": "Inclusive UTC date lower bound. Defaults to 30 days ago."
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "required": false,
            "description": "Inclusive UTC date upper bound. Defaults to today."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000,
              "default": 50
            },
            "required": false
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Pagination cursor returned as next_cursor."
          },
          {
            "name": "api_key_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Restrict to a developer-owned API key."
          },
          {
            "name": "platform_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Restrict to X-Platform-ID / platform attribution."
          },
          {
            "name": "path",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "example": "/v1/chat/completions"
          },
          {
            "name": "model",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "example": "gpt-4.1-nano"
          },
          {
            "name": "provider",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "description": "Public provider label or provider key. Public responses use labels such as OpenAI, Google, and VIABLE Lab."
          },
          {
            "name": "operation",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": false,
            "example": "chat"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 100,
              "maximum": 599
            },
            "required": false
          },
          {
            "name": "streaming",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "required": false
          },
          {
            "name": "include_payload",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "required": false,
            "description": "Includes sanitized request/response payloads when true. Prompt and file content remain subject to API logging redaction settings."
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "jsonl"
              ],
              "default": "csv"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Export file content.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/developer/logs/{request_id}": {
      "get": {
        "tags": [
          "Developer Platform"
        ],
        "summary": "Get Developer Request Log Detail",
        "description": "Returns one developer-owned data-plane request log row. Use `include_payload=true` to include sanitized request and response payload fields. Prompt and file content remain subject to API logging redaction settings.",
        "operationId": "getDeveloperRequestLog",
        "security": [
          {
            "FirebaseBearer": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Request UUID returned as `request_id` by `/v1/developer/logs`. Legacy numeric log IDs remain accepted for existing links."
          },
          {
            "name": "include_payload",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Includes sanitized request/response payloads when true."
          }
        ],
        "responses": {
          "200": {
            "description": "Developer-owned request log detail.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeveloperLogDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "StatusResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "message": {
            "type": "string",
            "example": "VIABLE Lab API is running"
          },
          "documentation": {
            "type": "string",
            "format": "url",
            "example": "https://developers.viablelab.org/"
          }
        }
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The model identifier or alias used in API requests.",
            "example": "viable-2"
          },
          "object": {
            "type": "string",
            "example": "model"
          },
          "mode": {
            "type": "string",
            "enum": [
              "chat",
              "embedding",
              "image_generation",
              "audio_transcription",
              "audio_speech"
            ],
            "description": "Endpoint mode this model supports."
          },
          "endpoint": {
            "type": "string",
            "description": "Primary API endpoint for the model.",
            "example": "/v1/chat/completions"
          },
          "description": {
            "type": "string"
          },
          "owned_by": {
            "type": "string",
            "description": "Public owner label for display and filtering."
          },
          "intelligence": {
            "type": "string"
          },
          "speed": {
            "type": "string"
          },
          "input_modalities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "text",
              "image"
            ]
          },
          "output_modalities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "text"
            ]
          },
          "context_window": {
            "type": "integer",
            "nullable": true
          },
          "max_output_tokens": {
            "type": "integer",
            "nullable": true
          },
          "supports_streaming": {
            "type": "boolean"
          },
          "capabilities": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            },
            "description": "Capability flags for text, images, files, PDFs, audio, tools, embeddings, and image generation."
          },
          "pricing": {
            "$ref": "#/components/schemas/PricingInfo"
          },
          "default_voice": {
            "type": "string",
            "description": "Default voice for compatible speech models."
          }
        }
      },
      "ModelListResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "list"
          },
          "default_model": {
            "type": "string",
            "example": "gpt-4.1-nano"
          },
          "aliases": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Legacy compatibility alias map. VIABLE aliases are listed in supported_aliases and available_models without exposing internal routing targets."
          },
          "available_models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          },
          "upcoming_models": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "supported_aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Supported public aliases and compatibility aliases accepted in the model field. VIABLE aliases are stable public model IDs; internal routing targets are not exposed."
          }
        }
      },
      "ChatCompletionRequest": {
        "type": "object",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            },
            "description": "A list of messages comprising the conversation history, ending with the latest user message."
          },
          "model": {
            "type": "string",
            "description": "Full model ID or VIABLE alias to use. Defaults to gpt-4.1-nano. Examples: gpt-4.1-nano, gpt-4o, gemini-2.5-flash, gpt-oss-120b, llama-3.1-70b-instruct, viable-2. Legacy short aliases remain accepted for existing integrations; new integrations should use full model IDs or VIABLE aliases.",
            "example": "gpt-4.1-nano"
          },
          "max_tokens": {
            "type": "integer",
            "description": "Maximum number of tokens to generate. Overrides router's default if lower."
          },
          "temperature": {
            "type": "number",
            "format": "float",
            "default": 1,
            "minimum": 0,
            "maximum": 2
          },
          "top_p": {
            "type": "number",
            "format": "float",
            "default": 1,
            "minimum": 0,
            "maximum": 1
          },
          "n": {
            "type": "integer",
            "default": 1,
            "description": "How many chat completion choices to generate. (Passed through)"
          },
          "stop": {
            "description": "Up to 4 sequences where the API will stop generating. (Passed through)",
            "nullable": true,
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "maxItems": 4
              }
            ]
          },
          "presence_penalty": {
            "type": "number",
            "format": "float",
            "default": 0
          },
          "frequency_penalty": {
            "type": "number",
            "format": "float",
            "default": 0
          },
          "response_format": {
            "type": "object",
            "description": "An object specifying the format that the model must output. Use { \"type\": \"json_object\" } to enable JSON mode, which ensures the message the model generates is valid JSON. Note: The model needs instructions in the prompt to produce JSON.",
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "text"
                    ],
                    "description": "The default format. Model generates text responses."
                  }
                },
                "required": [
                  "type"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "json_object"
                    ],
                    "description": "Ensures the model output is a valid JSON object."
                  }
                },
                "required": [
                  "type"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "json_schema"
                    ],
                    "description": "Ensures the model output adheres to a provided JSON schema."
                  },
                  "json_schema": {
                    "type": "object",
                    "description": "Configuration including the JSON Schema the model must follow.",
                    "required": [
                      "name"
                    ],
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "The name for the schema.",
                        "maxLength": 64
                      },
                      "description": {
                        "type": "string",
                        "description": "Description of the schema for the model."
                      },
                      "schema": {
                        "type": "object",
                        "description": "The JSON Schema object itself.",
                        "additionalProperties": true
                      },
                      "strict": {
                        "type": "boolean",
                        "description": "Whether to enforce strict adherence to the schema.",
                        "default": false
                      }
                    }
                  }
                },
                "required": [
                  "type",
                  "json_schema"
                ]
              }
            ],
            "example": {
              "type": "json_object"
            }
          },
          "stream": {
            "type": "boolean",
            "description": "If true, returns OpenAI-style server-sent events from /v1/chat/completions. Streaming is supported on the main chat endpoint; vetting endpoints remain non-streaming.",
            "default": false
          },
          "provider": {
            "type": "string",
            "enum": [
              "openai",
              "gemini"
            ],
            "description": "Optional provider hint for public providers. Most clients should omit this and rely on model-first routing."
          }
        },
        "description": "Standard OpenAI-compatible Chat Completion request. Supports text and multimodal content parts. The main chat endpoint supports streaming."
      },
      "ChatMessage": {
        "type": "object",
        "required": [
          "role",
          "content"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant",
              "system"
            ],
            "description": "The role of the message author."
          },
          "content": {
            "oneOf": [
              {
                "type": "string",
                "description": "The text content of the message."
              },
              {
                "type": "array",
                "description": "An array combining text, image, file, and PDF inputs for multimodal models.",
                "items": {
                  "type": "object",
                  "oneOf": [
                    {
                      "required": [
                        "type",
                        "text"
                      ],
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "text"
                          ],
                          "description": "Type identifier for text content.",
                          "example": "text"
                        },
                        "text": {
                          "type": "string",
                          "description": "The text content.",
                          "example": "What is in this image?"
                        }
                      }
                    },
                    {
                      "required": [
                        "type",
                        "image_url"
                      ],
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "image_url"
                          ],
                          "description": "Type identifier for image URL content.",
                          "example": "image_url"
                        },
                        "image_url": {
                          "type": "object",
                          "required": [
                            "url"
                          ],
                          "properties": {
                            "url": {
                              "type": "string",
                              "format": "uri",
                              "description": "The URL of the image.",
                              "example": "https://upload.wikimedia.org/..."
                            }
                          }
                        }
                      }
                    },
                    {
                      "required": [
                        "type",
                        "file"
                      ],
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "file",
                            "input_file"
                          ],
                          "description": "Type identifier for file content."
                        },
                        "file": {
                          "type": "object",
                          "required": [
                            "file_data"
                          ],
                          "properties": {
                            "filename": {
                              "type": "string"
                            },
                            "mime_type": {
                              "type": "string",
                              "example": "application/pdf"
                            },
                            "file_data": {
                              "type": "string",
                              "description": "Base64 file data, preferably as a data URI."
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      },
      "CompletionUsage": {
        "type": "object",
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          }
        },
        "description": "Token usage statistics for the completion request (non-streaming)."
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "param": {
                "type": "string",
                "nullable": true
              },
              "code": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "ChatVettingRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ChatCompletionRequest"
          }
        ],
        "type": "object",
        "properties": {
          "vettingConfig": {
            "$ref": "#/components/schemas/ChatVettingConfig",
            "description": "(Optional) Configuration for the VETTING pass."
          },
          "messages": {
            "description": "Conversation history. System message can be included here."
          },
          "model": {
            "description": "Full chat model ID or VIABLE alias. Defaults apply if omitted. See /v1/models for supported chat models.",
            "example": "viable-3"
          }
        }
      },
      "ChatVettingConfig": {
        "type": "object",
        "properties": {
          "systemPrompt": {
            "type": "string",
            "description": "(Optional) A specific guideline for the internal verification model to check against. If omitted, a default safety/guidance prompt is used.",
            "example": "Do not provide code directly, only explain the concepts."
          },
          "maxAttempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 3,
            "description": "(Optional) Maximum number of internal generation/verification attempts."
          }
        }
      },
      "ChatVettingResponse": {
        "description": "Response format for Chat Vetting, including standard OpenAI fields and vetting metadata.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ChatCompletionResponse"
          }
        ],
        "type": "object",
        "properties": {
          "vetting_info": {
            "$ref": "#/components/schemas/ChatVettingInfo",
            "description": "Information about the internal vetting process."
          },
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionChoice"
            }
          },
          "usage": {
            "$ref": "#/components/schemas/CompletionUsage"
          },
          "safety_signals": {
            "description": "Signals related to the safety and content appropriateness of the response.",
            "type": "object",
            "properties": {
              "requires_attention": {
                "type": "boolean",
                "description": "Indicates if the model flagged its own response as potentially addressing sensitive, harmful, or inappropriate topics, requiring human review or specific handling."
              }
            },
            "required": [
              "requires_attention"
            ]
          }
        }
      },
      "ChatVettingInfo": {
        "description": "Metadata about the VETTING pass for /v1/chat/vetting.",
        "type": "object",
        "required": [
          "attemptCount",
          "stopReason"
        ],
        "properties": {
          "attemptCount": {
            "type": "integer",
            "description": "Total number of internal generation/verification attempts made."
          },
          "stopReason": {
            "type": "string",
            "enum": [
              "VERIFICATION_PASSED",
              "MAX_ATTEMPTS_REACHED",
              "GENERATION_ERROR",
              "VERIFICATION_ERROR",
              "SAFETY_TRIGGERED"
            ],
            "description": "The reason the internal vetting process stopped. `SAFETY_TRIGGERED` indicates the chat model detected potentially harmful content based on the query/topic and halted the process before verification."
          },
          "lastFailureReason": {
            "type": "string",
            "nullable": true,
            "description": "If verification failed at least once before ultimately passing or hitting max attempts, this field contains the failure reason provided by the verification model for the *most recent* failure. Null if the first attempt passed, or if the process stopped early due to SAFETY_TRIGGERED or an error on the first attempt."
          }
        }
      },
      "ChatCompletionChoice": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "example": 0
          },
          "message": {
            "$ref": "#/components/schemas/ChatMessage"
          },
          "finish_reason": {
            "type": "string",
            "example": "stop",
            "enum": [
              "stop",
              "length",
              "error"
            ]
          },
          "logprobs": {
            "nullable": true,
            "description": "Log probability information, null if not requested/supported."
          }
        }
      },
      "ChatCompletionResponse": {
        "description": "Standard Chat Completion response format (OpenAI compatible).",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "chatcmpl-xxxxxxxxxxxxxxxxxxxxxxx"
          },
          "object": {
            "type": "string",
            "example": "chat.completion"
          },
          "created": {
            "type": "integer",
            "format": "int64",
            "example": 1677652288
          },
          "model": {
            "type": "string",
            "description": "The model requested by the client.",
            "example": "viable-3"
          },
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionChoice"
            }
          },
          "usage": {
            "$ref": "#/components/schemas/CompletionUsage"
          },
          "system_fingerprint": {
            "type": "string",
            "nullable": true,
            "description": "System fingerprint, null if not provided."
          }
        }
      },
      "VETTINGRequest": {
        "type": "object",
        "required": [
          "mode",
          "config",
          "prompts",
          "messages"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "vetting",
              "chat"
            ],
            "description": "(Required) Operation mode: 'vetting' enables the verification layer, 'chat' provides standard chat."
          },
          "config": {
            "$ref": "#/components/schemas/VETTINGConfig",
            "description": "(Required) Configuration for models and verification attempts."
          },
          "prompts": {
            "$ref": "#/components/schemas/VETTINGPrompts",
            "description": "(Required) Base system prompts object. Fields within this object are optional and have defaults (see VETTINGPrompts schema)."
          },
          "context": {
            "$ref": "#/components/schemas/VETTINGContext",
            "description": "(Optional) Contextual information. The 'items' array within is required if mode is 'vetting'."
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            },
            "description": "(Required) Conversation history, ending with the last user message. Client should provide messages with roles 'user' and optionally previous 'assistant' messages. Do not include 'system' role messages here; use the `prompts` field instead."
          }
        }
      },
      "VETTINGConfig": {
        "type": "object",
        "required": [
          "chatModel"
        ],
        "properties": {
          "maxVerificationAttempts": {
            "type": "integer",
            "minimum": 1,
            "default": 3,
            "description": "(Optional) Maximum verification attempts in 'vetting' mode. Defaults to 3 if omitted."
          },
          "chatModel": {
            "$ref": "#/components/schemas/ModelConfig",
            "description": "(Required) Configuration for the chat model."
          },
          "verificationModel": {
            "$ref": "#/components/schemas/ModelConfig",
            "description": "(Required if mode='vetting') Configuration for the verification model."
          }
        }
      },
      "ModelConfig": {
        "type": "object",
        "required": [
          "modelId"
        ],
        "properties": {
          "modelId": {
            "type": "string",
            "description": "(Required) Full chat model ID or VIABLE alias. Examples: viable-2, gpt-4.1-nano, gpt-4o-mini, gemini-2.5-flash, gpt-oss-120b, llama-3.1-70b-instruct. See /v1/models for the current catalog. Non-chat models are rejected on VETTING endpoints.",
            "example": "viable-3"
          },
          "temperature": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "maximum": 2,
            "description": "(Optional) Sampling temperature. If omitted, server defaults apply (e.g., Chat: 0.7, Verify: 0.1)."
          },
          "maxTokens": {
            "type": "integer",
            "minimum": 1,
            "description": "(Optional) Maximum tokens to generate. If omitted, server defaults apply (e.g., Chat: 1024, Verify: 512)."
          },
          "topP": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "maximum": 1,
            "description": "(Optional) Nucleus sampling parameter."
          }
        }
      },
      "VETTINGPrompts": {
        "type": "object",
        "description": "Container for system prompts. The object itself is required in the request, but the fields within are optional.",
        "properties": {
          "chatSystemPrompt": {
            "type": "string",
            "description": "(Optional) Base system prompt for the chat model. If omitted, a default helpful tutor prompt is used."
          },
          "verificationSystemPrompt": {
            "type": "string",
            "description": "(Optional) Base system prompt for the verification model. If omitted and mode='vetting', a default evaluator prompt is constructed using the chat prompt and context."
          }
        }
      },
      "VETTINGContext": {
        "type": "object",
        "description": "Contextual information. The 'items' array is required if mode='vetting'.",
        "properties": {
          "sessionId": {
            "type": "string",
            "nullable": true,
            "description": "(Optional) Session identifier."
          },
          "userId": {
            "type": "string",
            "nullable": true,
            "description": "(Optional) User identifier."
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/VettingContextItem"
            },
            "description": "(Required if mode='vetting') Array of questions and their corresponding answer keys."
          }
        },
        "required": [
          "items"
        ]
      },
      "VettingContextItem": {
        "type": "object",
        "required": [
          "question",
          "answerKey"
        ],
        "description": "A single question and its associated answer key for the VETTING context.",
        "properties": {
          "question": {
            "$ref": "#/components/schemas/QuestionInfo",
            "description": "(Required) Details about the question being discussed."
          },
          "answerKey": {
            "$ref": "#/components/schemas/AnswerKey",
            "description": "(Required) Reference answer details for verification."
          }
        }
      },
      "QuestionInfo": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "(Optional) Unique identifier for the question."
          },
          "text": {
            "type": "string",
            "description": "(Required) The text of the question being discussed."
          },
          "subject": {
            "type": "string",
            "nullable": true,
            "description": "(Optional) Subject area."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true,
            "description": "(Optional) Additional metadata."
          }
        }
      },
      "AnswerKey": {
        "type": "object",
        "required": [
          "correctAnswer"
        ],
        "properties": {
          "correctAnswer": {
            "type": "string",
            "description": "(Required) The correct answer, used by the verification layer."
          },
          "keyConcepts": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true,
            "description": "(Optional) List of key concepts/terms that should not be directly revealed."
          },
          "explanation": {
            "type": "string",
            "nullable": true,
            "description": "(Optional) Detailed explanation for the verification layer."
          }
        }
      },
      "VETTINGResponse": {
        "type": "object",
        "required": [
          "status",
          "mode",
          "result",
          "usage",
          "metadata",
          "safety_signals"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "success"
            ],
            "description": "Indicates successful processing."
          },
          "mode": {
            "type": "string",
            "enum": [
              "vetting",
              "chat"
            ],
            "description": "The mode used for this response."
          },
          "result": {
            "$ref": "#/components/schemas/VettingResult",
            "description": "The final assistant message content."
          },
          "safety_signals": {
            "description": "Signals related to the safety and content appropriateness of the primary chat response.",
            "type": "object",
            "properties": {
              "requires_attention": {
                "type": "boolean",
                "description": "Indicates if the chat model perceived the user query or topic as potentially harmful/sensitive and triggered the safety protocol (`stopReason: SAFETY_TRIGGERED`)."
              }
            },
            "required": [
              "requires_attention"
            ]
          },
          "verification": {
            "description": "Details about the verification attempts, only present in 'vetting' mode.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/VerificationDetails"
              },
              {
                "type": "null"
              }
            ]
          },
          "usage": {
            "$ref": "#/components/schemas/UsageInfo",
            "description": "Aggregated token usage for the request."
          },
          "metadata": {
            "$ref": "#/components/schemas/VETTINGMetadata"
          }
        }
      },
      "VerificationDetails": {
        "type": "object",
        "nullable": true,
        "required": [
          "passed",
          "attemptCount",
          "stopReason",
          "attempts"
        ],
        "properties": {
          "passed": {
            "type": "boolean",
            "description": "Indicates if the final response passed verification (true if mode='chat')."
          },
          "attemptCount": {
            "type": "integer",
            "description": "Total number of chat generation attempts made."
          },
          "stopReason": {
            "type": "string",
            "enum": [
              "VERIFICATION_PASSED",
              "MAX_ATTEMPTS_REACHED",
              "GENERATION_ERROR",
              "VERIFICATION_ERROR",
              "SAFETY_TRIGGERED"
            ],
            "description": "Reason the vetting process stopped. `SAFETY_TRIGGERED` indicates the chat model detected potentially harmful content and halted the process before this verification attempt."
          },
          "attempts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttemptDetail"
            },
            "description": "Details of each verification attempt."
          }
        }
      },
      "AttemptDetail": {
        "type": "object",
        "required": [
          "attemptNumber",
          "chatResponse",
          "verificationPassed",
          "verificationOutput"
        ],
        "properties": {
          "attemptNumber": {
            "type": "integer",
            "description": "The sequence number of this attempt."
          },
          "chatResponse": {
            "type": "string",
            "description": "The response generated by the chat model for this attempt."
          },
          "verificationPassed": {
            "type": "boolean",
            "description": "Whether this specific attempt passed verification."
          },
          "requiresAttention": {
            "type": "boolean",
            "description": "Indicates if the chat model flagged its *own response* in this attempt as potentially sensitive/harmful (based on user query/topic). True if the `stopReason` for the overall request is `SAFETY_TRIGGERED`."
          },
          "verificationOutput": {
            "type": "string",
            "description": "The raw output from the verification model ('PASS' or failure reason, or 'N/A (Safety Triggered)' if skipped)."
          }
        }
      },
      "UsageInfo": {
        "type": "object",
        "required": [
          "chatTokens",
          "totalTokens"
        ],
        "properties": {
          "chatTokens": {
            "$ref": "#/components/schemas/TokenUsageDetail",
            "description": "Token usage for the chat model calls."
          },
          "verificationTokens": {
            "$ref": "#/components/schemas/TokenUsageDetail",
            "nullable": true,
            "description": "Token usage for the verification model calls (null if mode='chat')."
          },
          "totalTokens": {
            "type": "integer",
            "description": "Total estimated tokens used for the entire request."
          }
        }
      },
      "TokenUsageDetail": {
        "type": "object",
        "required": [
          "prompt",
          "completion",
          "total"
        ],
        "properties": {
          "prompt": {
            "type": "integer"
          },
          "completion": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "VETTINGMetadata": {
        "type": "object",
        "required": [
          "processingTimeMs",
          "timestamp",
          "chatModelUsed"
        ],
        "properties": {
          "processingTimeMs": {
            "type": "integer",
            "description": "Total time taken by the API call in milliseconds."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "sessionId": {
            "type": "string",
            "nullable": true
          },
          "userId": {
            "type": "string",
            "nullable": true
          },
          "chatModelUsed": {
            "type": "string",
            "description": "Requested chat model ID or alias used for drafting."
          },
          "verificationModelUsed": {
            "type": "string",
            "nullable": true,
            "description": "Requested verification model ID or alias used for VETTING verification (null if mode='chat')."
          },
          "calculatedCost": {
            "type": "number",
            "nullable": true,
            "description": "Estimated total request cost in USD when all selected models have registry pricing; null when any selected model has unknown pricing."
          }
        }
      },
      "VETTINGErrorResponse": {
        "type": "object",
        "required": [
          "status",
          "error",
          "metadata"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "error"
            ],
            "example": "error"
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Error code (e.g., INVALID_INPUT, MODEL_ERROR, INTERNAL_ERROR)."
              },
              "message": {
                "type": "string",
                "description": "Human-readable error description."
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "nullable": true,
                "description": "Optional array of specific validation errors if code is INVALID_INPUT."
              }
            }
          },
          "metadata": {
            "type": "object",
            "required": [
              "timestamp"
            ],
            "properties": {
              "timestamp": {
                "type": "string",
                "format": "date-time"
              },
              "requestId": {
                "type": "string",
                "nullable": true,
                "description": "Optional request tracking ID."
              }
            }
          }
        }
      },
      "AudioSpeechRequest": {
        "type": "object",
        "required": [
          "input",
          "model"
        ],
        "properties": {
          "input": {
            "type": "string",
            "description": "The text to generate audio for. Maximum length: 4096 characters.",
            "maxLength": 4096,
            "example": "VIABLE Lab builds AI-powered learning and research tools."
          },
          "model": {
            "type": "string",
            "description": "Speech model ID. OpenAI-compatible choices include gpt-4o-mini-tts, tts-1, and tts-1-hd; registered VIABLE Lab speech models such as kokoro are also supported.",
            "enum": [
              "gpt-4o-mini-tts",
              "tts-1",
              "tts-1-hd",
              "kokoro"
            ],
            "example": "gpt-4o-mini-tts"
          },
          "voice": {
            "type": "string",
            "description": "Voice to use for generation. Required for OpenAI speech models; optional for registered speech models with a default voice.",
            "example": "alloy"
          },
          "instructions": {
            "type": "string",
            "description": "(Optional) Control the voice of your generated audio with additional instructions. Does not work with tts-1 or tts-1-hd.",
            "example": "Speak in a slightly older, male voice with a British accent."
          },
          "response_format": {
            "type": "string",
            "description": "The format for the audio output.",
            "enum": [
              "mp3",
              "opus",
              "aac",
              "flac",
              "wav",
              "pcm"
            ],
            "default": "mp3",
            "example": "mp3"
          },
          "speed": {
            "type": "number",
            "format": "float",
            "description": "The speed of the generated audio (0.25 to 4.0).",
            "minimum": 0.25,
            "maximum": 4,
            "default": 1,
            "example": 1
          }
        }
      },
      "PricingInfo": {
        "type": "object",
        "properties": {
          "input_per_million": {
            "type": "number",
            "nullable": true,
            "description": "USD per million input tokens."
          },
          "output_per_million": {
            "type": "number",
            "nullable": true,
            "description": "USD per million output tokens."
          },
          "cached_input_per_million": {
            "type": "number",
            "nullable": true,
            "description": "USD per million cached input tokens."
          },
          "image_per_unit": {
            "type": "number",
            "nullable": true,
            "description": "USD per generated image when known."
          },
          "audio_per_minute": {
            "type": "number",
            "nullable": true,
            "description": "USD per audio minute when known."
          },
          "status": {
            "type": "string",
            "example": "documented",
            "description": "Pricing status for the model, such as documented, starts_at, docs_inferred, short_context, or not_listed."
          },
          "note": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "EmbeddingRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "nomic-embed-text-v1.5",
            "example": "nomic-embed-text-v1.5"
          },
          "input": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "example": "Searchable text"
          },
          "encoding_format": {
            "type": "string",
            "enum": [
              "float",
              "base64"
            ],
            "default": "float"
          },
          "dimensions": {
            "type": "integer",
            "description": "Optional dimensions if supported by the selected model."
          }
        }
      },
      "EmbeddingResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "object": {
                  "type": "string",
                  "example": "embedding"
                },
                "index": {
                  "type": "integer"
                },
                "embedding": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/CompletionUsage"
          }
        }
      },
      "ImageGenerationRequest": {
        "type": "object",
        "required": [
          "prompt"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "flux.2-klein",
            "example": "flux.2-klein"
          },
          "prompt": {
            "type": "string",
            "example": "A modern classroom dashboard in a clean product UI style"
          },
          "n": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 1
          },
          "size": {
            "type": "string",
            "example": "1024x1024"
          },
          "quality": {
            "type": "string",
            "example": "standard"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "url",
              "b64_json"
            ],
            "default": "url"
          }
        }
      },
      "ImageGenerationResponse": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string"
                },
                "b64_json": {
                  "type": "string"
                },
                "revised_prompt": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "AudioTranscriptionRequest": {
        "type": "object",
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Audio file upload."
          },
          "model": {
            "type": "string",
            "default": "whisper-large-v3",
            "example": "whisper-large-v3",
            "description": "Transcription model ID. Defaults to whisper-large-v3. OpenAI-compatible choices include gpt-4o-transcribe, gpt-4o-mini-transcribe, and whisper-1.",
            "enum": [
              "whisper-large-v3",
              "gpt-4o-transcribe",
              "gpt-4o-mini-transcribe",
              "whisper-1"
            ]
          },
          "language": {
            "type": "string",
            "description": "Optional ISO-639-1 language code."
          },
          "prompt": {
            "type": "string"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "json",
              "text",
              "srt",
              "verbose_json",
              "vtt"
            ],
            "default": "json"
          },
          "temperature": {
            "type": "number"
          },
          "duration_seconds": {
            "type": "number",
            "description": "Optional client-supplied duration for accurate cost logging."
          },
          "duration_minutes": {
            "type": "number",
            "description": "Optional client-supplied duration for accurate cost logging."
          }
        }
      },
      "AudioTranscriptionResponse": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "example": "Transcribed audio text."
          }
        },
        "additionalProperties": true
      },
      "DocsMetadataResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "viablelab.api_metadata"
          },
          "version": {
            "type": "string"
          },
          "base_url": {
            "type": "string",
            "example": "https://api.viablelab.org"
          },
          "default_model": {
            "type": "string"
          },
          "default_models_by_mode": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "modes": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Model"
              }
            }
          },
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          },
          "endpoints": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "quickstarts": {
            "type": "object"
          },
          "pricing_notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cache": {
            "type": "object"
          },
          "agent_guide_url": {
            "type": "string",
            "example": "https://developers.viablelab.org/agents/viablelab-api.md"
          }
        }
      },
      "DeveloperUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "firebase_uid": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "display_name": {
            "type": "string",
            "nullable": true
          },
          "photo_url": {
            "type": "string",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "example": "google"
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_login_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "DeveloperProfileResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "developer.user"
          },
          "user": {
            "$ref": "#/components/schemas/DeveloperUser"
          },
          "developer": {
            "$ref": "#/components/schemas/DeveloperUser"
          }
        }
      },
      "DeveloperApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "key_abc123"
          },
          "name": {
            "type": "string"
          },
          "key_prefix": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "revoked"
            ]
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowed_models": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            }
          },
          "limits": {
            "$ref": "#/components/schemas/DeveloperApiKeyLimits"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_used_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "revoked_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "DeveloperApiKeyLimits": {
        "type": "object",
        "properties": {
          "rate_limit_per_minute": {
            "type": "integer",
            "nullable": true
          },
          "daily_token_limit": {
            "type": "integer",
            "nullable": true
          },
          "monthly_cost_limit_usd": {
            "type": "number",
            "nullable": true
          }
        }
      },
      "DeveloperApiKeyListResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeveloperApiKey"
            }
          },
          "api_keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeveloperApiKey"
            }
          }
        }
      },
      "DeveloperApiKeyResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "developer.api_key"
          },
          "api_key": {
            "$ref": "#/components/schemas/DeveloperApiKey"
          }
        }
      },
      "DeveloperApiKeySecretResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "developer.api_key"
          },
          "api_key": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeveloperApiKey"
              },
              {
                "type": "object",
                "properties": {
                  "key": {
                    "type": "string",
                    "example": "vlab_sk_key_xxx_secret"
                  }
                }
              }
            ]
          },
          "warning": {
            "type": "string"
          }
        }
      },
      "CreateDeveloperApiKeyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "model:request"
            ]
          },
          "allowedModels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "rateLimitPerMinute": {
            "type": "integer",
            "nullable": true
          },
          "dailyTokenLimit": {
            "type": "integer",
            "nullable": true
          },
          "monthlyCostLimitUsd": {
            "type": "number",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "UpdateDeveloperApiKeyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "model:request"
            ]
          },
          "allowedModels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "rateLimitPerMinute": {
            "type": "integer",
            "nullable": true
          },
          "dailyTokenLimit": {
            "type": "integer",
            "nullable": true
          },
          "monthlyCostLimitUsd": {
            "type": "number",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ],
            "description": "Use paused to temporarily block requests without rotating the secret."
          }
        }
      },
      "DeveloperUsageResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "developer.usage"
          },
          "usage": {
            "type": "object",
            "properties": {
              "from": {
                "type": "string",
                "format": "date"
              },
              "to": {
                "type": "string",
                "format": "date"
              },
              "totals": {
                "$ref": "#/components/schemas/DeveloperUsageTotals"
              },
              "daily": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DeveloperUsageDaily"
                }
              }
            }
          },
          "totals": {
            "$ref": "#/components/schemas/DeveloperUsageTotals"
          },
          "daily": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeveloperUsageDaily"
            }
          }
        }
      },
      "DeveloperUsageTotals": {
        "type": "object",
        "properties": {
          "request_count": {
            "type": "integer"
          },
          "requests": {
            "type": "integer"
          },
          "error_count": {
            "type": "integer"
          },
          "errors": {
            "type": "integer"
          },
          "tokens_used": {
            "type": "integer"
          },
          "tokens": {
            "type": "integer"
          },
          "cost_usd": {
            "type": "number"
          }
        }
      },
      "DeveloperUsageDaily": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DeveloperUsageTotals"
          },
          {
            "type": "object",
            "properties": {
              "usage_date": {
                "type": "string",
                "format": "date"
              },
              "api_key_id": {
                "type": "string"
              }
            }
          }
        ]
      },
      "DeveloperLogFilters": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date"
          },
          "to": {
            "type": "string",
            "format": "date"
          },
          "api_key_id": {
            "type": "string",
            "nullable": true
          },
          "platform_id": {
            "type": "string",
            "nullable": true
          },
          "path": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true,
            "example": "VIABLE Lab"
          },
          "operation": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "nullable": true
          },
          "streaming": {
            "type": "boolean",
            "nullable": true
          },
          "limit": {
            "type": "integer"
          },
          "cursor": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "DeveloperLogEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "timestamp_utc": {
            "type": "string",
            "example": "2026-06-09 18:30:00"
          },
          "request_id": {
            "type": "string",
            "nullable": true
          },
          "api_key_id": {
            "type": "string",
            "nullable": true
          },
          "api_key_prefix": {
            "type": "string",
            "nullable": true
          },
          "api_key_name": {
            "type": "string",
            "nullable": true
          },
          "platform_id": {
            "type": "string",
            "nullable": true
          },
          "platform_name": {
            "type": "string",
            "nullable": true
          },
          "endpoint": {
            "type": "string",
            "example": "/v1/chat/completions"
          },
          "request_path": {
            "type": "string"
          },
          "request_method": {
            "type": "string",
            "example": "POST"
          },
          "function_name": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true,
            "example": "gpt-4.1-nano"
          },
          "model_name": {
            "type": "string",
            "nullable": true
          },
          "requested_model": {
            "type": "string",
            "nullable": true,
            "example": "viable-2"
          },
          "provider": {
            "type": "string",
            "nullable": true,
            "example": "OpenAI"
          },
          "operation": {
            "type": "string",
            "nullable": true,
            "example": "chat"
          },
          "status": {
            "type": "integer",
            "nullable": true,
            "example": 200
          },
          "response_status": {
            "type": "integer",
            "nullable": true
          },
          "tokens_used": {
            "type": "integer"
          },
          "cost_usd": {
            "type": "number",
            "nullable": true
          },
          "processing_time": {
            "type": "number",
            "nullable": true,
            "description": "Request processing time in seconds."
          },
          "streaming": {
            "type": "boolean"
          },
          "error_message": {
            "type": "string",
            "nullable": true
          },
          "multimodal": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "usage_units": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "request_body": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Only present when include_payload is true."
          },
          "response_body": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Only present when include_payload is true."
          }
        }
      },
      "DeveloperLogListResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "developer.log_list"
          },
          "filters": {
            "$ref": "#/components/schemas/DeveloperLogFilters"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeveloperLogEntry"
            }
          },
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeveloperLogEntry"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "DeveloperLogDetailResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "developer.log"
          },
          "log": {
            "$ref": "#/components/schemas/DeveloperLogEntry"
          },
          "request_log": {
            "$ref": "#/components/schemas/DeveloperLogEntry"
          }
        }
      }
    },
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token authentication (Planned for future enforcement)."
      },
      "FirebaseBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Firebase ID token",
        "description": "Firebase ID token from Google sign-in. Used only for developer dashboard management endpoints."
      },
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "VIABLE Lab API key",
        "description": "VIABLE Lab API key generated from the developer dashboard. Required for protected API usage when API_KEY_ENFORCEMENT is required."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Authentication failed. Invalid or missing Bearer token (Not currently enforced).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Invalid authentication credentials",
                "type": "invalid_request_error",
                "code": "authentication_failed"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Access denied. Request source (Origin/Referer via CORS) might be invalid (temporary check), or insufficient permissions (future).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Forbidden: Invalid Origin.",
                "type": "forbidden_error",
                "code": "invalid_origin"
              }
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "Method Not Allowed. The HTTP method used is not supported for this endpoint.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Method Not Allowed",
                "type": "invalid_request_error",
                "code": "method_not_allowed"
              }
            }
          }
        }
      },
      "BadRequest": {
        "description": "Bad Request. The request payload is malformed, contains invalid parameters, or failed validation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Invalid request body: JSON parsing failed",
                "type": "invalid_request_error",
                "code": "invalid_json"
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too Many Requests. Rate limit exceeded.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Rate limit exceeded",
                "type": "requests_error",
                "code": "rate_limit_exceeded"
              }
            }
          }
        }
      },
      "NotImplemented": {
        "description": "Not Implemented. The requested functionality is not available.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Endpoint not implemented",
                "type": "not_implemented_error",
                "code": "not_implemented"
              }
            }
          }
        }
      },
      "ServerError": {
        "description": "Internal Server Error. An unexpected error occurred on the server.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Internal Server Error",
                "type": "api_error",
                "code": "internal_error"
              }
            }
          }
        }
      },
      "BadAPI": {
        "description": "Upstream model service error. Error occurred when communicating with a model provider.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": {
                "message": "Error from model provider: 500",
                "type": "service_error",
                "code": "model_provider_error"
              }
            }
          }
        }
      }
    }
  }
}
