{
  "openapi": "3.1.0",
  "info": {
    "title": "Perceptron API",
    "contact": {
      "name": "Perceptron API Support",
      "email": "support@perceptron.inc"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.perceptron.inc"
    }
  ],
  "paths": {
    "/v1/chat/completions": {
      "post": {
        "tags": ["Chat Completions"],
        "summary": "Create chat completion",
        "description": "Generate a response for a text or multimodal conversation, using the OpenAI chat completions request and response format.",
        "operationId": "handle_chat_completions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChatCompletionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Chat completion generated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateChatCompletionResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "$ref": "#/components/schemas/CreateChatCompletionStreamResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request was invalid or could not be processed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "examples": {
                  "audio_token_limit_exceeded": {
                    "summary": "An audio item, or the audio track of a video, exceeds the model's audio limit. Audio is never truncated.",
                    "value": {
                      "error": {
                        "message": "Audio at messages[0].content[1] is 912.4 s (11405 audio tokens). This model accepts at most 8192 audio tokens per item (about 655 s). Audio is not truncated; shorten or split it.",
                        "type": "invalid_request_error",
                        "param": "messages[0].content[1].input_audio",
                        "code": "audio_token_limit_exceeded"
                      }
                    }
                  },
                  "tool_calling_not_supported": {
                    "summary": "The request declares tools, or has tool calls or results in `messages`, and the model does not support tool calling",
                    "value": {
                      "error": {
                        "message": "Model 'perceptron-mk1' does not support tool calling",
                        "type": "invalid_request_error",
                        "param": "tools",
                        "code": "unsupported_parameter"
                      }
                    }
                  },
                  "unsupported_input": {
                    "summary": "The model does not support an input in the request",
                    "value": {
                      "error": {
                        "message": "Model 'test' does not support video input",
                        "type": "invalid_request_error",
                        "param": null,
                        "code": null
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded or quota exceeded. Too many requests or insufficient credits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Organization rate limit exceeded (300 requests/minute). Please retry after 30 seconds.",
                    "type": "rate_limit_error",
                    "param": null,
                    "code": "rate_limit_exceeded"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "503": {
            "description": "The model is temporarily overloaded and dropped the request before processing it. Retry after the number of seconds in the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The model is currently overloaded with other requests. Please retry after a short wait.",
                    "type": "server_error",
                    "param": null,
                    "code": "model_overloaded"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v1/chat/completions/multilook": {
      "post": {
        "tags": ["Chat Completions"],
        "summary": "Create multilook chat completions",
        "description": "Run several independent prompts over one shared, prefilled context.",
        "operationId": "handle_multilook_completions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMultilookRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Multilook completions generated successfully. Returns a grouped response with one result per prompt; a prompt-level failure appears as an `error` entry in place of that prompt's completions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MultilookResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request was invalid or could not be processed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid n: 12. Expected a value between 1 and 8.",
                    "type": "invalid_request_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded or quota exceeded. Too many requests or insufficient credits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Organization rate limit exceeded (150 requests/minute). Please retry after 30 seconds.",
                    "type": "rate_limit_error",
                    "param": null,
                    "code": "rate_limit_exceeded"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v1/detect": {
      "post": {
        "tags": ["Detection"],
        "summary": "Detect objects",
        "description": "Return grounded object detections for a single image from text categories, annotated exemplars, or exhaustive detection.",
        "operationId": "handle_detect",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DetectRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Detection completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DetectResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid detection request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PerceptronErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PerceptronErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PerceptronErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal error while processing detection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PerceptronErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v1/files": {
      "get": {
        "tags": ["Files"],
        "summary": "List files",
        "description": "Returns a paginated list of files belonging to the caller's organization.\nCursor pagination via `after`; see the `limit` and `order` parameters for defaults.",
        "operationId": "handle_list_files",
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "description": "Cursor for pagination — the `id` of the last file from the previous page.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of objects to return (1-10000, default 10000).",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            }
          },
          {
            "name": "order",
            "in": "query",
            "description": "Sort order by `created_at`.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/SortOrder"
            }
          },
          {
            "name": "purpose",
            "in": "query",
            "description": "Filter files by purpose.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/FilePurpose"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of files.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListFilesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter (bad `limit`, unknown `after` cursor, etc.).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "'limit' must be between 1 and 10000 (got 0)",
                    "type": "invalid_request_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": ["Files"],
        "summary": "Upload a file",
        "description": "Accepts a single file via multipart upload alongside a `purpose` field that\ndeclares how the file will be used. Subject to per-file and per-organization\nstorage limits.",
        "operationId": "handle_upload_file",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UploadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "File uploaded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — missing field, unsupported content type, etc.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Unsupported content type 'text/plain'. Supported: image/jpeg, image/png, image/webp, video/mp4, video/quicktime, video/webm, audio/wav, audio/mpeg, audio/flac",
                    "type": "invalid_request_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "411": {
            "description": "Missing `Content-Length` header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Content-Length header is required for /v1/files.",
                    "type": "invalid_request_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "413": {
            "description": "Upload would exceed the per-file or per-organization storage limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "You exceeded your current quota, please check your plan and billing details.",
                    "type": "insufficient_quota",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the upload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl https://api.perceptron.inc/v1/files \\\n  -H \"Authorization: Bearer $PERCEPTRON_API_KEY\" \\\n  -F purpose=vision \\\n  -F 'file=@video.mp4'"
          }
        ]
      }
    },
    "/v1/files/{file_id}": {
      "get": {
        "tags": ["Files"],
        "summary": "Retrieve a file",
        "description": "Returns metadata for a single file (size, content type, purpose, etc.).\nUse the `/v1/files/{file_id}/content` endpoint to download the bytes.",
        "operationId": "handle_retrieve_file",
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "description": "The id of the file to retrieve.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "No such File object: file-missing",
                    "type": "invalid_request_error",
                    "param": "id",
                    "code": null
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "tags": ["Files"],
        "summary": "Delete a file",
        "description": "Permanently deletes a file. Once deleted, the file can no longer be\nretrieved, downloaded, or referenced in requests. Returns 404 if no file\nwith the given id exists.",
        "operationId": "handle_delete_file",
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "description": "The id of the file to delete.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteFileResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "No such File object: file-missing",
                    "type": "invalid_request_error",
                    "param": "id",
                    "code": null
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v1/files/{file_id}/content": {
      "get": {
        "tags": ["Files"],
        "summary": "Download a file's contents",
        "description": "Returns the raw bytes with the file's stored `Content-Type` header.",
        "operationId": "handle_retrieve_file_content",
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "description": "The id of the file whose contents to return.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File bytes. The response `Content-Type` matches what was supplied at upload time.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "integer",
                    "format": "int32",
                    "minimum": 0
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "No such File object: file-missing",
                    "type": "invalid_request_error",
                    "param": "id",
                    "code": null
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while fetching file contents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v1/models": {
      "get": {
        "tags": ["Models"],
        "summary": "List available models",
        "description": "Returns a list of models available in the API. Use the `extended` query parameter\nto get additional metadata about each model's capabilities and supported features.",
        "operationId": "handle_get_models",
        "parameters": [
          {
            "name": "extended",
            "in": "query",
            "description": "If true, returns extended model metadata including capabilities, modalities, and limits.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of available models. Returns `GetModelsResponse` when `extended=false` (default), or `GetModelsExtendedResponse` when `extended=true`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetModelsResponseUnion"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Organization rate limit exceeded (30 requests/minute). Please retry after 30 seconds.",
                    "type": "rate_limit_error",
                    "param": null,
                    "code": "rate_limit_exceeded"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v1/models/{model_id}": {
      "get": {
        "tags": ["Models"],
        "summary": "Retrieve a model",
        "description": "Returns a specific model by its ID. Use the `extended` query parameter\nto get additional metadata about the model's capabilities and supported features.",
        "operationId": "handle_get_model",
        "parameters": [
          {
            "name": "model_id",
            "in": "path",
            "description": "The ID of the model to retrieve.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "extended",
            "in": "query",
            "description": "If true, returns extended model metadata including capabilities, modalities, and limits.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The model with the given ID. Returns `Model` when `extended=false` (default), or `ModelExtended` when `extended=true`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetModelResponseUnion"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed. Invalid or missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid API key",
                    "type": "authentication_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          },
          "404": {
            "description": "Model not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The model 'unknown-model' does not exist",
                    "type": "invalid_request_error",
                    "param": "model",
                    "code": "model_not_found"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Organization rate limit exceeded (30 requests/minute). Please retry after 30 seconds.",
                    "type": "rate_limit_error",
                    "param": null,
                    "code": "rate_limit_exceeded"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error while processing the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAIErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "The server had an error while processing your request.",
                    "type": "server_error",
                    "param": null,
                    "code": null
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AnnotationFormat": {
        "type": "string",
        "description": "Annotation format the model should emit alongside text output.",
        "enum": ["point", "box", "polygon", "clip"]
      },
      "AudioFileId": {
        "type": "object",
        "description": "Reference to an uploaded audio file by its id (e.g. `file-abc...`).",
        "required": ["file_id"],
        "properties": {
          "file_id": {
            "type": "string"
          }
        }
      },
      "AudioUrl": {
        "type": "object",
        "description": "Audio file reference (an HTTP(S) URL or a base64 data URL). Supported formats are WAV, MP3, and FLAC.",
        "required": ["url"],
        "properties": {
          "url": {
            "type": "string"
          }
        }
      },
      "Capability": {
        "type": "string",
        "description": "Special capabilities that a model may support.",
        "enum": ["response_format_json_schema", "regex", "tool_calling"]
      },
      "ChatChoice": {
        "type": "object",
        "description": "Individual completion sampled by the model.",
        "required": ["index", "message"],
        "properties": {
          "finish_reason": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FinishReason"
              }
            ]
          },
          "index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "message": {
            "$ref": "#/components/schemas/ChatCompletionResponseMessage"
          }
        }
      },
      "ChatChoiceStream": {
        "type": "object",
        "description": "Streaming choice emitted per SSE chunk.",
        "required": ["index"],
        "properties": {
          "delta": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ChatCompletionStreamResponseDelta"
              }
            ]
          },
          "finish_reason": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FinishReason"
              }
            ]
          },
          "index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          }
        }
      },
      "ChatCompletionMessageToolCall": {
        "type": "object",
        "description": "A tool call the model made.",
        "required": ["id", "type", "function"],
        "properties": {
          "function": {
            "$ref": "#/components/schemas/FunctionCall"
          },
          "id": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ToolType"
          }
        }
      },
      "ChatCompletionMessageToolCallChunk": {
        "type": "object",
        "description": "A streamed piece of a tool call. The first piece for an `index` carries the call's `id`,\n`type` and `function.name`; later pieces carry only `function.arguments`, to be appended.",
        "required": ["index"],
        "properties": {
          "function": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FunctionCallStream"
              }
            ]
          },
          "id": {
            "type": ["string", "null"]
          },
          "index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "type": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ToolType"
              }
            ]
          }
        }
      },
      "ChatCompletionNamedToolChoice": {
        "type": "object",
        "description": "A `tool_choice` that forces a call to the named function.",
        "required": ["type", "function"],
        "properties": {
          "function": {
            "$ref": "#/components/schemas/FunctionName"
          },
          "type": {
            "$ref": "#/components/schemas/ToolType"
          }
        }
      },
      "ChatCompletionRequestAssistantMessage": {
        "type": "object",
        "description": "Single chat message within the request payload.",
        "properties": {
          "content": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ChatCompletionRequestAssistantMessageContent",
                "description": "The text of the message. May be `null` or omitted when the message has `tool_calls`."
              }
            ]
          },
          "reasoning_content": {
            "type": ["string", "null"],
            "description": "The `reasoning_content` the model returned for this turn. Send it back with the turn's\n`tool_calls` so the model sees the reasoning it generated. Ignored on requests with neither\n`tools` nor tool calls or results in `messages`."
          },
          "tool_calls": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/ChatCompletionMessageToolCall"
            },
            "description": "The tool calls the model made in this turn. Requires a model that supports tool calling."
          }
        }
      },
      "ChatCompletionRequestAssistantMessageContent": {
        "oneOf": [
          {
            "type": "string",
            "title": "Text"
          },
          {
            "type": "array",
            "title": "Content parts",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestAssistantMessageContentPart"
            }
          }
        ],
        "description": "Chat completion message content as either a string or structured content array."
      },
      "ChatCompletionRequestAssistantMessageContentPart": {
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartText"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["text"]
                  }
                }
              }
            ],
            "title": "Text"
          }
        ]
      },
      "ChatCompletionRequestMessage": {
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestSystemMessage"
              },
              {
                "type": "object",
                "required": ["role"],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": ["system"]
                  }
                }
              }
            ],
            "title": "System"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestSystemMessage",
                "description": "Treated as `system`."
              },
              {
                "type": "object",
                "required": ["role"],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": ["developer"]
                  }
                }
              }
            ],
            "title": "Developer",
            "description": "Treated as `system`."
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestUserMessage"
              },
              {
                "type": "object",
                "required": ["role"],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": ["user"]
                  }
                }
              }
            ],
            "title": "User"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestAssistantMessage"
              },
              {
                "type": "object",
                "required": ["role"],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": ["assistant"]
                  }
                }
              }
            ],
            "title": "Assistant"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestToolMessage"
              },
              {
                "type": "object",
                "required": ["role"],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": ["tool"]
                  }
                }
              }
            ],
            "title": "Tool"
          }
        ],
        "description": "Author role of the message: `system`, `developer`, `user`, `assistant`, or `tool`."
      },
      "ChatCompletionRequestMessageContentPartAudio": {
        "type": "object",
        "description": "Audio content part containing a URL.",
        "required": ["audio_url"],
        "properties": {
          "audio_url": {
            "$ref": "#/components/schemas/AudioUrl"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartAudioFileId": {
        "type": "object",
        "description": "Audio content part referencing an uploaded file by id.",
        "required": ["audio_file_id"],
        "properties": {
          "audio_file_id": {
            "$ref": "#/components/schemas/AudioFileId"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartImage": {
        "type": "object",
        "description": "Image content part containing a URL.",
        "required": ["image_url"],
        "properties": {
          "image_url": {
            "$ref": "#/components/schemas/ImageUrl"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartImageFileId": {
        "type": "object",
        "description": "Image content part referencing an uploaded file by id.",
        "required": ["image_file_id"],
        "properties": {
          "image_file_id": {
            "$ref": "#/components/schemas/ImageFileId"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartInputAudio": {
        "type": "object",
        "description": "Audio content part carrying inline base64 audio.",
        "required": ["input_audio"],
        "properties": {
          "input_audio": {
            "$ref": "#/components/schemas/InputAudio"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartText": {
        "type": "object",
        "description": "Text chunk inside a structured message.",
        "required": ["text"],
        "properties": {
          "text": {
            "type": "string"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartVideo": {
        "type": "object",
        "description": "Video content part containing a URL.",
        "required": ["video_url"],
        "properties": {
          "video_url": {
            "$ref": "#/components/schemas/VideoUrl"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartVideoFileId": {
        "type": "object",
        "description": "Video content part referencing an uploaded file by id.",
        "required": ["video_file_id"],
        "properties": {
          "video_file_id": {
            "$ref": "#/components/schemas/VideoFileId"
          }
        }
      },
      "ChatCompletionRequestMessageContentPartVideoFrames": {
        "type": "object",
        "description": "Content part carrying raw video frames the caller has already decoded, as an\nalternative to a single `video_url`.",
        "required": ["video_frames"],
        "properties": {
          "video_frames": {
            "$ref": "#/components/schemas/VideoFrames"
          }
        }
      },
      "ChatCompletionRequestSystemMessage": {
        "type": "object",
        "description": "Single chat message within the request payload.",
        "required": ["content"],
        "properties": {
          "content": {
            "$ref": "#/components/schemas/ChatCompletionRequestSystemMessageContent"
          }
        }
      },
      "ChatCompletionRequestSystemMessageContent": {
        "oneOf": [
          {
            "type": "string",
            "title": "Text"
          },
          {
            "type": "array",
            "title": "Content parts",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestSystemMessageContentPart"
            }
          }
        ],
        "description": "Chat completion message content as either a string or structured content array."
      },
      "ChatCompletionRequestSystemMessageContentPart": {
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartText"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["text"]
                  }
                }
              }
            ],
            "title": "Text"
          }
        ]
      },
      "ChatCompletionRequestToolMessage": {
        "type": "object",
        "description": "The result of a tool call, sent back to the model. Requires a model that supports tool calling.",
        "required": ["tool_call_id", "content"],
        "properties": {
          "content": {
            "$ref": "#/components/schemas/ChatCompletionRequestToolMessageContent",
            "description": "The result, as text or as `text`, `image_url` and `image_file_id` parts. Images count toward\nthe request's media limit and need a model that accepts image input."
          },
          "tool_call_id": {
            "type": "string",
            "description": "The `id` of the tool call this message answers."
          }
        }
      },
      "ChatCompletionRequestToolMessageContent": {
        "oneOf": [
          {
            "type": "string",
            "title": "Text"
          },
          {
            "type": "array",
            "title": "Content parts",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestToolMessageContentPart"
            }
          }
        ],
        "description": "Tool result content as either a string or structured content array."
      },
      "ChatCompletionRequestToolMessageContentPart": {
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartText"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["text"]
                  }
                }
              }
            ],
            "title": "Text"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartImage"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["image_url"]
                  }
                }
              }
            ],
            "title": "Image URL"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartImageFileId"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["image_file_id"]
                  }
                }
              }
            ],
            "title": "Image file ID"
          }
        ]
      },
      "ChatCompletionRequestUserMessage": {
        "type": "object",
        "description": "Single chat message within the request payload.",
        "required": ["content"],
        "properties": {
          "content": {
            "$ref": "#/components/schemas/ChatCompletionRequestUserMessageContent"
          }
        }
      },
      "ChatCompletionRequestUserMessageContent": {
        "oneOf": [
          {
            "type": "string",
            "title": "Text"
          },
          {
            "type": "array",
            "title": "Content parts",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestUserMessageContentPart"
            }
          }
        ],
        "description": "Chat completion message content as either a string or structured content array."
      },
      "ChatCompletionRequestUserMessageContentPart": {
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartText"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["text"]
                  }
                }
              }
            ],
            "title": "Text"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartImage"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["image_url"]
                  }
                }
              }
            ],
            "title": "Image URL"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartVideo"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["video_url"]
                  }
                }
              }
            ],
            "title": "Video URL"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartVideoFrames"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["video_frames"]
                  }
                }
              }
            ],
            "title": "Video frames"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartImageFileId"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["image_file_id"]
                  }
                }
              }
            ],
            "title": "Image file ID"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartVideoFileId"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["video_file_id"]
                  }
                }
              }
            ],
            "title": "Video file ID"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartInputAudio"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["input_audio"]
                  }
                }
              }
            ],
            "title": "Input audio"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartAudio"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["audio_url"]
                  }
                }
              }
            ],
            "title": "Audio URL"
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionRequestMessageContentPartAudioFileId"
              },
              {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": ["audio_file_id"]
                  }
                }
              }
            ],
            "title": "Audio file ID"
          }
        ]
      },
      "ChatCompletionResponseFormat": {
        "oneOf": [
          {
            "type": "object",
            "required": ["type"],
            "properties": {
              "type": {
                "type": "string",
                "enum": ["text"]
              }
            }
          },
          {
            "type": "object",
            "required": ["json_schema", "type"],
            "properties": {
              "json_schema": {
                "$ref": "#/components/schemas/ChatCompletionResponseFormatJsonSchema"
              },
              "type": {
                "type": "string",
                "enum": ["json_schema"]
              }
            }
          }
        ]
      },
      "ChatCompletionResponseFormatJsonSchema": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string"
          },
          "schema": {},
          "strict": {
            "type": ["boolean", "null"],
            "description": "When true, the model output will strictly adhere to the provided schema."
          }
        }
      },
      "ChatCompletionResponseMessage": {
        "type": "object",
        "description": "Message object returned in the assistant's response.",
        "required": ["content", "role"],
        "properties": {
          "content": {
            "type": ["string", "null"],
            "description": "The text of the message, `null` when there is none (for example when the model only\ncalled tools)."
          },
          "reasoning_content": {
            "type": ["string", "null"]
          },
          "role": {
            "$ref": "#/components/schemas/Role"
          },
          "tool_calls": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/ChatCompletionMessageToolCall"
            },
            "description": "The tool calls the model made."
          }
        }
      },
      "ChatCompletionStreamOptions": {
        "type": "object",
        "description": "Streaming flags accepted by the API.",
        "properties": {
          "include_usage": {
            "type": ["boolean", "null"],
            "description": "Include token usage metrics with streaming responses."
          }
        }
      },
      "ChatCompletionStreamResponseDelta": {
        "type": "object",
        "description": "Delta payload for streaming responses.",
        "properties": {
          "content": {
            "type": ["string", "null"]
          },
          "reasoning_content": {
            "type": ["string", "null"]
          },
          "role": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Role"
              }
            ]
          },
          "tool_calls": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/ChatCompletionMessageToolCallChunk"
            }
          }
        }
      },
      "ChatCompletionTool": {
        "oneOf": [
          {
            "type": "object",
            "title": "Function",
            "description": "A function the caller runs when the model calls it.",
            "required": ["function", "type"],
            "properties": {
              "function": {
                "$ref": "#/components/schemas/FunctionObject"
              },
              "type": {
                "type": "string",
                "enum": ["function"]
              }
            }
          }
        ],
        "description": "A function the caller runs when the model calls it."
      },
      "ChatCompletionToolChoiceOption": {
        "oneOf": [
          {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ToolChoiceMode"
              }
            ],
            "title": "Mode"
          },
          {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChatCompletionNamedToolChoice"
              }
            ],
            "title": "Named function"
          }
        ],
        "description": "Whether the model may call the declared tools. Only `auto` and `none` are supported."
      },
      "CompletionUsage": {
        "type": "object",
        "description": "Token accounting emitted with every completion.",
        "required": ["prompt_tokens", "completion_tokens", "total_tokens"],
        "properties": {
          "completion_tokens": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "prompt_tokens": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "prompt_tokens_details": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/PromptTokensDetails",
                "description": "Present when the model reports a per-modality breakdown."
              }
            ]
          },
          "total_tokens": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          }
        }
      },
      "CreateChatCompletionRequest": {
        "type": "object",
        "required": ["messages", "model"],
        "properties": {
          "frequency_penalty": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Positive values discourage the model from repeating previously used tokens.",
            "maximum": 2,
            "minimum": -2
          },
          "max_completion_tokens": {
            "type": ["integer", "null"],
            "format": "int32",
            "description": "Maximum number of completion tokens to generate. Must fit within the selected model's context and output limits.",
            "minimum": 0
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestMessage"
            },
            "description": "Conversation history listed in order. Supported roles: `system`, `developer` (treated as `system`),\n`user`, `assistant`, `tool`."
          },
          "model": {
            "type": "string",
            "description": "The model to invoke. Use `GET /v1/models` to discover available model IDs. New Perceptron requests should use\n`perceptron-mk1.5`."
          },
          "n": {
            "type": ["integer", "null"],
            "format": "int32",
            "description": "Number of completions to generate. Only `1` is supported; greater values are rejected.",
            "maximum": 1,
            "minimum": 1
          },
          "parallel_tool_calls": {
            "type": ["boolean", "null"],
            "description": "Whether the model may call several functions in one turn. Defaults to `true`. Ignored\nwithout functions in `tools`."
          },
          "presence_penalty": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Positive values encourage the model to introduce new concepts.",
            "maximum": 2,
            "minimum": -2
          },
          "reasoning_effort": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ReasoningEffort",
                "description": "How much the model reasons before it answers: `none`, `minimal`, `low`, `medium` or `high`.\nA tier other than `none` turns reasoning on. `vision_config.enable_thinking`, when set,\ndecides whether the model reasons; the tier then only applies while reasoning is on."
              }
            ]
          },
          "regex": {
            "type": ["string", "null"],
            "description": "Regex pattern for constrained generation."
          },
          "response_format": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ChatCompletionResponseFormat",
                "description": "An object specifying the format that the model must output.\nSetting to `{ \"type\": \"json_schema\", \"json_schema\": {...} }` enables Structured Outputs\nwhich ensures the model will match your supplied JSON schema."
              }
            ]
          },
          "stream": {
            "type": ["boolean", "null"],
            "description": "Set to `true` for SSE streaming. When omitted, the API returns a single JSON response.",
            "default": false
          },
          "stream_options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ChatCompletionStreamOptions",
                "description": "Optional streaming flags. Token usage is always reported in the final chunk of a streaming response."
              }
            ]
          },
          "temperature": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Sampling temperature. Lower values yield deterministic replies; higher values explore more creative outputs.",
            "maximum": 2,
            "minimum": 0
          },
          "tool_choice": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ChatCompletionToolChoiceOption",
                "description": "Whether the model may call the declared functions: `auto` (the default) or `none`. `none` is\nbest effort and does not guarantee a response without tool calls. Forcing a call (`required`\nor a named function) is not supported and is rejected with a 400. Ignored without functions\nin `tools`."
              }
            ]
          },
          "tools": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/ChatCompletionTool"
            },
            "description": "Functions the model may call and the caller executes. Cannot be combined with a\n`json_schema` `response_format` or `regex`.\n\nFunctions require a model that supports tool calling: other models reject them, and tool\ncalls or results in `messages`, with a 400. Generation stops at the first turn that calls\nfunctions, so a response carries at most one turn of `tool_calls`."
          },
          "top_k": {
            "type": ["integer", "null"],
            "format": "int32",
            "description": "Top-k sampling. The model samples from the top k most likely tokens.",
            "minimum": 0
          },
          "top_p": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Nucleus sampling probability. The model samples from the smallest token set whose cumulative probability exceeds this threshold.",
            "maximum": 1,
            "exclusiveMinimum": 0
          },
          "vision_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/VisionConfig",
                "description": "Perceptron vision-model controls (thinking, spatial output format,\nvideo audio). Only supported on Perceptron-owned models."
              }
            ]
          }
        }
      },
      "CreateChatCompletionResponse": {
        "type": "object",
        "description": "Non-streaming response body when `stream=false`.",
        "required": ["id", "choices", "created", "model", "object"],
        "properties": {
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatChoice"
            }
          },
          "created": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "id": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "usage": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/CompletionUsage"
              }
            ]
          }
        }
      },
      "CreateChatCompletionStreamResponse": {
        "type": "object",
        "description": "SSE response payload when `stream=true`.",
        "required": ["id", "choices", "created", "model", "object"],
        "properties": {
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatChoiceStream"
            }
          },
          "created": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "id": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "usage": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/CompletionUsage"
              }
            ]
          }
        }
      },
      "CreateMultilookRequest": {
        "type": "object",
        "description": "Request body for `/v1/chat/completions/multilook`.",
        "required": ["model", "context", "prompts"],
        "properties": {
          "context": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestMessage"
            },
            "description": "Shared prefix all prompts extend — same message format as `/v1/chat/completions`, except that\ntool calling is not supported: `tool` messages and assistant `tool_calls` are rejected with a\n400. Prefilled once and reused across all prompts within this request."
          },
          "frequency_penalty": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Positive values discourage the model from repeating previously used tokens.",
            "maximum": 2,
            "minimum": -2
          },
          "max_completion_tokens": {
            "type": ["integer", "null"],
            "format": "int32",
            "description": "Maximum completion tokens, per completion. Must fit within the selected model's\noutput limit.",
            "minimum": 0
          },
          "model": {
            "type": "string",
            "description": "The model to invoke."
          },
          "n": {
            "type": ["integer", "null"],
            "format": "int32",
            "description": "Sampled completions (\"looks\") per prompt (1 to 8). `n > 1` requires `temperature > 0`.",
            "default": 1,
            "maximum": 8,
            "minimum": 1
          },
          "presence_penalty": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Positive values encourage the model to introduce new concepts.",
            "maximum": 2,
            "minimum": -2
          },
          "prompts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MultilookPromptInput"
            },
            "description": "Independent sequences extending the shared prefix (1 to 16 entries). Prompts are\nisolated from one another and never see each other's text or completions.",
            "maxItems": 16,
            "minItems": 1
          },
          "reasoning_effort": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ReasoningEffort",
                "description": "How much the model reasons before it answers: `none`, `minimal`, `low`, `medium` or `high`.\nOne tier for the whole request, applied to every prompt. A tier other than `none` turns\nreasoning on. `vision_config.enable_thinking`, when set, decides whether the model reasons;\nthe tier then only applies while reasoning is on."
              }
            ]
          },
          "temperature": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Sampling temperature, shared across all prompts.",
            "maximum": 2,
            "minimum": 0
          },
          "top_k": {
            "type": ["integer", "null"],
            "format": "int32",
            "description": "Top-k sampling.",
            "minimum": 0
          },
          "top_p": {
            "type": ["number", "null"],
            "format": "float",
            "description": "Nucleus sampling probability.",
            "maximum": 1,
            "exclusiveMinimum": 0
          },
          "vision_config": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/VisionConfig",
                "description": "Perceptron vision-model controls, shared across all prompts."
              }
            ]
          }
        }
      },
      "DeleteFileResponse": {
        "type": "object",
        "required": ["object", "id", "deleted"],
        "properties": {
          "deleted": {
            "type": "boolean",
            "description": "Whether the file was successfully deleted."
          },
          "id": {
            "type": "string",
            "description": "ID of the deleted file."
          },
          "object": {
            "type": "string",
            "description": "Always \"file\"."
          }
        }
      },
      "DetectConfig": {
        "type": "object",
        "properties": {
          "enable_thinking": {
            "type": ["boolean", "null"],
            "description": "Deprecated: use `reasoning_effort`. `true` is `high` and `false` is `none`; ignored when\n`reasoning_effort` is set.",
            "deprecated": true
          },
          "output": {
            "$ref": "#/components/schemas/DetectOutput"
          },
          "reasoning_effort": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ReasoningEffort",
                "description": "How much the model reasons before it answers: `none` (the default), `minimal`, `low`,\n`medium` or `high`. A tier other than `none` turns reasoning on. Only image-only detection\n(no categories or exemplars) reasons."
              }
            ]
          }
        },
        "additionalProperties": false
      },
      "DetectExemplar": {
        "type": "object",
        "required": ["media", "annotations"],
        "properties": {
          "annotations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DetectPointPrimitive"
            }
          },
          "media": {
            "$ref": "#/components/schemas/DetectMedia"
          }
        }
      },
      "DetectFinishReason": {
        "type": "string",
        "enum": ["complete", "max_tokens"]
      },
      "DetectMedia": {
        "oneOf": [
          {
            "type": "object",
            "required": ["image_url", "type"],
            "properties": {
              "image_url": {
                "type": "string",
                "description": "Image URL or data URL. Video is not supported by /v1/detect yet."
              },
              "type": {
                "type": "string",
                "enum": ["image"]
              }
            }
          }
        ]
      },
      "DetectNegativeExemplar": {
        "type": "object",
        "required": ["media"],
        "properties": {
          "media": {
            "$ref": "#/components/schemas/DetectMedia",
            "description": "Image known not to contain requested target objects."
          }
        }
      },
      "DetectOutput": {
        "type": "string",
        "enum": ["box", "point"]
      },
      "DetectPoint": {
        "type": "object",
        "required": ["x", "y"],
        "properties": {
          "x": {
            "type": "number",
            "format": "double",
            "description": "X coordinate in image pixels."
          },
          "y": {
            "type": "number",
            "format": "double",
            "description": "Y coordinate in image pixels."
          }
        }
      },
      "DetectPointBox": {
        "type": "object",
        "required": ["top_left", "bottom_right"],
        "properties": {
          "bottom_right": {
            "$ref": "#/components/schemas/DetectPoint"
          },
          "top_left": {
            "$ref": "#/components/schemas/DetectPoint"
          }
        }
      },
      "DetectPointPrimitive": {
        "type": "object",
        "required": ["mention"],
        "properties": {
          "index": {
            "type": ["integer", "null"],
            "format": "int64"
          },
          "label": {
            "type": ["string", "null"]
          },
          "mention": {
            "type": "string",
            "description": "Category/target identity for this exemplar annotation. Must not contain commas."
          },
          "point": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DetectPoint",
                "description": "Exemplar point annotation in exemplar-image pixel coordinates."
              }
            ]
          },
          "point_box": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DetectPointBox",
                "description": "Exemplar box annotation in exemplar-image pixel coordinates."
              }
            ]
          },
          "timestamp": {
            "type": ["number", "null"],
            "format": "double"
          }
        }
      },
      "DetectRequest": {
        "type": "object",
        "required": ["media"],
        "properties": {
          "categories": {
            "type": ["array", "null"],
            "items": {
              "type": "string"
            },
            "description": "Category names to detect. Entries must be non-empty and must not contain commas."
          },
          "config": {
            "$ref": "#/components/schemas/DetectConfig"
          },
          "exemplars": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/DetectExemplar"
            }
          },
          "media": {
            "$ref": "#/components/schemas/DetectMedia"
          },
          "negative_exemplars": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/DetectNegativeExemplar"
            }
          }
        },
        "additionalProperties": false
      },
      "DetectResponse": {
        "type": "object",
        "required": ["detections", "finish_reason"],
        "properties": {
          "detections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Detection"
            }
          },
          "finish_reason": {
            "$ref": "#/components/schemas/DetectFinishReason"
          }
        },
        "additionalProperties": false
      },
      "Detection": {
        "type": "object",
        "required": ["mention"],
        "properties": {
          "mention": {
            "type": "string"
          },
          "point": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DetectPoint",
                "description": "Point in target-image pixel coordinates."
              }
            ]
          },
          "point_box": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/DetectPointBox",
                "description": "Bounding box in target-image pixel coordinates."
              }
            ]
          }
        },
        "additionalProperties": false
      },
      "File": {
        "type": "object",
        "required": [
          "object",
          "id",
          "bytes",
          "created_at",
          "filename",
          "purpose"
        ],
        "properties": {
          "bytes": {
            "type": "integer",
            "format": "int64",
            "description": "File size in bytes."
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp (seconds) when the file was created."
          },
          "filename": {
            "type": "string",
            "description": "Original file name."
          },
          "id": {
            "type": "string",
            "description": "File ID, e.g. `file-abc123`."
          },
          "object": {
            "type": "string",
            "description": "Always \"file\"."
          },
          "purpose": {
            "$ref": "#/components/schemas/FilePurpose",
            "description": "File purpose."
          }
        }
      },
      "FilePurpose": {
        "type": "string",
        "enum": ["vision", "user_data"],
        "example": "vision"
      },
      "FinishReason": {
        "type": "string",
        "enum": [
          "stop",
          "length",
          "tool_calls",
          "tool_error",
          "tool_limit",
          "interrupted"
        ]
      },
      "FunctionCall": {
        "type": "object",
        "description": "A function the model called.",
        "required": ["name", "arguments"],
        "properties": {
          "arguments": {
            "type": "string",
            "description": "The arguments as the model generated them, meant to be JSON. They are not validated and\nmay be cut off when the response hit its token limit."
          },
          "name": {
            "type": "string"
          }
        }
      },
      "FunctionCallStream": {
        "type": "object",
        "description": "A streamed piece of a function call. Concatenate the `arguments` of every piece with the same\n`index`.",
        "properties": {
          "arguments": {
            "type": ["string", "null"]
          },
          "name": {
            "type": ["string", "null"]
          }
        }
      },
      "FunctionName": {
        "type": "object",
        "description": "The name of a function.",
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string"
          }
        }
      },
      "FunctionObject": {
        "type": "object",
        "description": "A function the model may call.",
        "required": ["name"],
        "properties": {
          "description": {
            "type": ["string", "null"],
            "description": "What the function does, which the model uses to choose when and how to call it."
          },
          "name": {
            "type": "string"
          },
          "parameters": {
            "type": "object",
            "description": "The arguments the function accepts, as a JSON Schema object. Kept exactly as sent, including\nthe order of its properties."
          },
          "strict": {
            "type": ["boolean", "null"],
            "description": "Accepted but not enforced: the arguments the model generates are not checked against\n`parameters`."
          }
        }
      },
      "GetModelResponseUnion": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/Model"
          },
          {
            "$ref": "#/components/schemas/ModelExtended"
          }
        ],
        "description": "Response union for GET /v1/models/{model_id} endpoint.\nReturns Model when extended=false (default), or ModelExtended when extended=true."
      },
      "GetModelsExtendedResponse": {
        "type": "object",
        "description": "Extended response for GET /v1/models?extended=true",
        "required": ["object", "data"],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelExtended"
            },
            "description": "List of available models with extended metadata."
          },
          "object": {
            "type": "string",
            "description": "Object type, always \"list\"."
          }
        }
      },
      "GetModelsResponse": {
        "type": "object",
        "description": "Response for `GET /v1/models`: the models available to the caller.",
        "required": ["object", "data"],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            },
            "description": "List of available models."
          },
          "object": {
            "type": "string",
            "description": "Object type, always \"list\"."
          }
        }
      },
      "GetModelsResponseUnion": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/GetModelsResponse"
          },
          {
            "$ref": "#/components/schemas/GetModelsExtendedResponse"
          }
        ],
        "description": "Response union for GET /v1/models endpoint.\nReturns GetModelsResponse when extended=false (default), or GetModelsExtendedResponse when extended=true."
      },
      "ImageFileId": {
        "type": "object",
        "description": "Reference to an uploaded image file by its id (e.g. `file-abc...`).",
        "required": ["file_id"],
        "properties": {
          "file_id": {
            "type": "string"
          }
        }
      },
      "ImageUrl": {
        "type": "object",
        "description": "Inline image reference (an HTTP(S) URL or a base64 data URL).",
        "required": ["url"],
        "properties": {
          "url": {
            "type": "string"
          }
        }
      },
      "InputAudio": {
        "type": "object",
        "description": "Inline audio: the file bytes as base64 plus their encoding.",
        "required": ["data", "format"],
        "properties": {
          "data": {
            "type": "string",
            "description": "Raw audio file bytes, base64 encoded, without a `data:` URI prefix."
          },
          "format": {
            "type": "string",
            "description": "Encoding of `data`: `wav`, `mp3`, or `flac`.",
            "example": "wav"
          }
        }
      },
      "ListFilesResponse": {
        "type": "object",
        "required": ["object", "data", "first_id", "last_id", "has_more"],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            },
            "description": "List of file objects."
          },
          "first_id": {
            "type": "string",
            "description": "ID of the first file in the returned page."
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether more results are available."
          },
          "last_id": {
            "type": "string",
            "description": "ID of the last file in the returned page."
          },
          "object": {
            "type": "string",
            "description": "Always \"list\"."
          }
        }
      },
      "Modality": {
        "type": "string",
        "description": "Types of modalities the model can accept.",
        "enum": ["image", "video", "audio"]
      },
      "Model": {
        "type": "object",
        "description": "A model's identity fields.",
        "required": ["id", "object", "created", "owned_by"],
        "properties": {
          "created": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp when the model was created."
          },
          "id": {
            "type": "string",
            "description": "The model identifier."
          },
          "object": {
            "type": "string",
            "description": "Object type, always \"model\"."
          },
          "owned_by": {
            "$ref": "#/components/schemas/Owner",
            "description": "The organization that owns the model."
          }
        }
      },
      "ModelExtended": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Model",
            "description": "Base model fields (id, object, created, owned_by)."
          },
          {
            "type": "object",
            "required": [
              "name",
              "capabilities",
              "modalities",
              "output_formats",
              "sampling_parameters",
              "reasoning",
              "max_context_tokens",
              "max_output_tokens",
              "credits_per_million_input_tokens",
              "credits_per_million_output_tokens",
              "credits_per_million_cache_read_tokens",
              "early_access"
            ],
            "properties": {
              "capabilities": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Capability"
                },
                "description": "List of special capabilities supported by this model."
              },
              "credits_per_million_cache_read_tokens": {
                "type": "integer",
                "format": "int64",
                "description": "Cost in credits per million cached prompt tokens (multilook prefill reuse).",
                "minimum": 0
              },
              "credits_per_million_input_tokens": {
                "type": "integer",
                "format": "int64",
                "description": "Cost in credits per million input tokens.",
                "minimum": 0
              },
              "credits_per_million_output_tokens": {
                "type": "integer",
                "format": "int64",
                "description": "Cost in credits per million output tokens.",
                "minimum": 0
              },
              "description": {
                "type": ["string", "null"],
                "description": "Optional description of the model."
              },
              "early_access": {
                "type": "boolean",
                "description": "Whether this model is in early access (preview)."
              },
              "max_context_tokens": {
                "type": "integer",
                "format": "int64",
                "description": "Maximum number of tokens in the context window.",
                "minimum": 0
              },
              "max_output_tokens": {
                "type": "integer",
                "format": "int64",
                "description": "Maximum number of tokens the model can output.",
                "minimum": 0
              },
              "modalities": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Modality"
                },
                "description": "List of modalities this model accepts."
              },
              "name": {
                "type": "string",
                "description": "Human-readable display name for the model."
              },
              "output_formats": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OutputFormat"
                },
                "description": "List of output formats this model can produce."
              },
              "reasoning": {
                "$ref": "#/components/schemas/Reasoning",
                "description": "Reasoning capability configuration."
              },
              "sampling_parameters": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SamplingParameter"
                },
                "description": "List of sampling parameters this model supports."
              }
            }
          }
        ],
        "description": "A model with its identity fields plus capabilities, limits, and pricing."
      },
      "MultilookCompletion": {
        "type": "object",
        "description": "One sampled completion for a prompt.",
        "required": ["index", "message"],
        "properties": {
          "finish_reason": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FinishReason"
              }
            ]
          },
          "index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "message": {
            "$ref": "#/components/schemas/ChatCompletionResponseMessage"
          }
        }
      },
      "MultilookPromptError": {
        "type": "object",
        "description": "Error for a single prompt (e.g. a content guard); the other prompts' results\nare unaffected.",
        "required": ["message"],
        "properties": {
          "code": {
            "type": ["string", "null"]
          },
          "message": {
            "type": "string"
          },
          "type": {
            "type": ["string", "null"]
          }
        }
      },
      "MultilookPromptInput": {
        "oneOf": [
          {
            "type": "string",
            "title": "Text prompt"
          },
          {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MultilookStructuredPrompt"
              }
            ],
            "title": "Structured prompt"
          }
        ],
        "description": "One prompt: the content of an implicit final `user` turn extending the shared\n`context`. Either a bare string or a structured object carrying content parts\n(the same part types as `/v1/chat/completions` user messages, including media)."
      },
      "MultilookPromptTokensDetails": {
        "type": "object",
        "description": "Breakdown of `prompt_tokens`, nested inside `usage`.",
        "required": ["cached_tokens", "audio_tokens"],
        "properties": {
          "audio_tokens": {
            "type": "integer",
            "format": "int32",
            "description": "Prompt tokens produced from audio input across every prompt: audio content parts and,\nwhen `vision_config.enable_audio_in_video` is set, video soundtracks. `0` means no audio\nwas analyzed.",
            "minimum": 0
          },
          "cached_tokens": {
            "type": "integer",
            "format": "int32",
            "description": "Subset of `prompt_tokens` served from the in-request prefill rather than\nrecomputed. Reuse is scoped to this request: a second identical call reports 0.",
            "minimum": 0
          }
        }
      },
      "MultilookPromptUsage": {
        "type": "object",
        "description": "Per-prompt usage. Completion tokens only; prompt tokens are reported once in the\ncall-level `usage` and never attributed to individual prompts.",
        "required": ["completion_tokens"],
        "properties": {
          "completion_tokens": {
            "type": "integer",
            "format": "int32",
            "description": "Summed across this prompt's `n` completions.",
            "minimum": 0
          }
        }
      },
      "MultilookResponse": {
        "type": "object",
        "description": "Response body for `/v1/chat/completions/multilook`.",
        "required": ["id", "object", "model", "results"],
        "properties": {
          "id": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "description": "Always `chat.completion.multilook`."
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MultilookResult"
            },
            "description": "One entry per prompt, in request order."
          },
          "usage": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/MultilookUsage"
              }
            ]
          }
        }
      },
      "MultilookResult": {
        "type": "object",
        "description": "Result for one prompt, in request order: either `completions` (+ `usage`) or `error`.",
        "required": ["prompt_index"],
        "properties": {
          "completions": {
            "type": ["array", "null"],
            "items": {
              "$ref": "#/components/schemas/MultilookCompletion"
            }
          },
          "error": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/MultilookPromptError"
              }
            ]
          },
          "prompt_index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "usage": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/MultilookPromptUsage"
              }
            ]
          }
        }
      },
      "MultilookStructuredPrompt": {
        "type": "object",
        "description": "Structured prompt content: the same content-part types as `/v1/chat/completions` user messages.",
        "required": ["content"],
        "properties": {
          "content": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatCompletionRequestUserMessageContentPart"
            }
          }
        }
      },
      "MultilookUsage": {
        "type": "object",
        "description": "Call-level usage. `prompt_tokens` counts the shared context once per prompt (same\nmeaning as on `/v1/chat/completions`); `total_tokens = prompt_tokens + completion_tokens`.",
        "required": [
          "prompt_tokens",
          "completion_tokens",
          "total_tokens",
          "prompt_tokens_details"
        ],
        "properties": {
          "completion_tokens": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "prompt_tokens": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "prompt_tokens_details": {
            "$ref": "#/components/schemas/MultilookPromptTokensDetails"
          },
          "total_tokens": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          }
        }
      },
      "OpenAIErrorDetail": {
        "type": "object",
        "description": "OpenAI-compatible error detail.",
        "required": ["message"],
        "properties": {
          "code": {
            "type": ["string", "null"]
          },
          "message": {
            "type": "string"
          },
          "param": {
            "type": ["string", "null"]
          },
          "type": {
            "type": ["string", "null"]
          }
        }
      },
      "OpenAIErrorResponse": {
        "type": "object",
        "description": "OpenAI-compatible error response format.",
        "required": ["error"],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/OpenAIErrorDetail"
          }
        }
      },
      "OutputFormat": {
        "type": "string",
        "description": "Types of output formats the model can produce.",
        "enum": ["text", "point", "box", "polygon", "clip"]
      },
      "Owner": {
        "type": "string",
        "description": "Owner of a model.",
        "enum": ["perceptron"]
      },
      "PerceptronErrorDetail": {
        "type": "object",
        "description": "Native Perceptron error detail.",
        "required": ["message"],
        "properties": {
          "code": {
            "type": ["string", "null"]
          },
          "message": {
            "type": "string"
          },
          "param": {
            "type": ["string", "null"]
          },
          "type": {
            "type": ["string", "null"]
          }
        }
      },
      "PerceptronErrorResponse": {
        "type": "object",
        "description": "Native Perceptron error response format.",
        "required": ["error"],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/PerceptronErrorDetail"
          }
        }
      },
      "PromptTokensDetails": {
        "type": "object",
        "description": "Breakdown of `prompt_tokens` by input modality.",
        "required": ["audio_tokens"],
        "properties": {
          "audio_tokens": {
            "type": "integer",
            "format": "int32",
            "description": "Prompt tokens produced from audio input: audio content parts and, when\n`vision_config.enable_audio_in_video` is set, video soundtracks. `0` means no audio was\nanalyzed, including when an opted-in video has no usable soundtrack.",
            "minimum": 0
          }
        }
      },
      "Reasoning": {
        "type": "object",
        "description": "Reasoning capability configuration for a model.",
        "required": ["supported", "always_enabled"],
        "properties": {
          "always_enabled": {
            "type": "boolean",
            "description": "Whether reasoning is always enabled for this model."
          },
          "supported": {
            "type": "boolean",
            "description": "Whether the model supports reasoning mode."
          }
        }
      },
      "ReasoningEffort": {
        "type": "string",
        "description": "How much the model reasons before it answers; `none` asks for no reasoning.",
        "enum": ["none", "minimal", "low", "medium", "high"]
      },
      "Role": {
        "type": "string",
        "enum": ["system", "user", "assistant"]
      },
      "SamplingParameter": {
        "type": "string",
        "description": "Sampling parameters the model supports for generation.",
        "enum": [
          "temperature",
          "top_p",
          "top_k",
          "frequency_penalty",
          "presence_penalty"
        ]
      },
      "SortOrder": {
        "type": "string",
        "enum": ["asc", "desc"]
      },
      "ToolChoiceMode": {
        "type": "string",
        "description": "A `tool_choice` mode.",
        "enum": ["none", "auto", "required"]
      },
      "ToolType": {
        "type": "string",
        "description": "The type of a tool call or a named tool choice. Always `function`.",
        "enum": ["function"]
      },
      "UploadRequest": {
        "type": "object",
        "description": "Multipart form body for `POST /v1/files`. Send the file bytes in the `file`\nfield and the file's intended `purpose`.",
        "required": ["file", "purpose"],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "The file to upload. Must be one of: `image/jpeg`, `image/png`, `image/webp`, `video/mp4`, `video/quicktime`, `video/webm`, `audio/wav`, `audio/mpeg`, `audio/flac`."
          },
          "purpose": {
            "$ref": "#/components/schemas/FilePurpose",
            "description": "File purpose."
          }
        }
      },
      "VideoFileId": {
        "type": "object",
        "description": "Reference to an uploaded video file by its id (e.g. `file-abc...`).",
        "required": ["file_id"],
        "properties": {
          "file_id": {
            "type": "string"
          }
        }
      },
      "VideoFrame": {
        "type": "object",
        "description": "A single decoded video frame: an image (HTTP(S) URL or base64 data URL) plus\nits timestamp within the clip.",
        "required": ["image_url", "timestamp_ms"],
        "properties": {
          "image_url": {
            "$ref": "#/components/schemas/ImageUrl"
          },
          "timestamp_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Offset of this frame from the start of the clip, in milliseconds. Timestamps must\nbe non-negative and non-decreasing across the `frames` array.",
            "minimum": 0
          }
        }
      },
      "VideoFrames": {
        "type": "object",
        "description": "An ordered sequence of decoded video frames passed inline.",
        "required": ["frames"],
        "properties": {
          "frames": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoFrame"
            },
            "minItems": 2
          }
        }
      },
      "VideoUrl": {
        "type": "object",
        "description": "Video asset referenced inside structured content arrays.",
        "required": ["url"],
        "properties": {
          "url": {
            "type": "string"
          }
        }
      },
      "VisionConfig": {
        "type": "object",
        "description": "Perceptron vision-model controls. Only honored by Perceptron-owned models.",
        "properties": {
          "annotation_format": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/AnnotationFormat",
                "description": "Annotation format the model should emit (`point`, `box`, `polygon`, or `clip`)."
              }
            ]
          },
          "enable_audio_in_video": {
            "type": ["boolean", "null"],
            "description": "When true, the audio track of each video in the request is analyzed along with its frames.\nDefaults to false. A video without an audio track is processed as video only. Audio content\nparts are analyzed regardless of this setting."
          },
          "enable_thinking": {
            "type": ["boolean", "null"],
            "description": "Deprecated: use the top-level `reasoning_effort`. When set, this flag decides whether the\nmodel reasons and the tier only applies while reasoning is on.",
            "deprecated": true
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token authentication using your Perceptron API key"
      }
    }
  },
  "tags": [
    {
      "name": "Chat Completions",
      "description": "Chat completions API (OpenAI-compatible)"
    },
    {
      "name": "Detection",
      "description": "Native Perceptron image detection API"
    },
    {
      "name": "Models",
      "description": "Model listing and metadata API"
    },
    {
      "name": "Files",
      "description": "File upload, listing, retrieval, and deletion API"
    }
  ]
}
