{
  "openapi": "3.1.0",
  "info": {
    "title": "Verbatik API",
    "version": "1.0.0",
    "description": "Create images, videos, speech, music, sound effects, reusable personas, custom voices, and multi-step Agent productions. Every generative operation is billed from the workspace credit balance.\n\nAuthenticate with `Authorization: Bearer <key>`. Owners and admins create workspace-scoped keys in **Settings → Developer**. An active subscription or any successful historical top-up unlocks API access.\n\nPOST requests accept `Idempotency-Key` for safe retries. The default limit is 60 requests/minute and 5 concurrent media jobs per workspace; Agent execution is limited to one live run per workspace.\n\nWebhook signatures cover `${webhook-timestamp}.${rawBody}` using HMAC-SHA256. Compare the result to `webhook-signature` (`v1=<hex>`) and reject timestamps older than five minutes."
  },
  "servers": [
    {
      "url": "https://app.verbatik.com/api",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Models"
    },
    {
      "name": "Files"
    },
    {
      "name": "Generations"
    },
    {
      "name": "Speech"
    },
    {
      "name": "Agents"
    },
    {
      "name": "Voices"
    },
    {
      "name": "Personas"
    },
    {
      "name": "Billing"
    },
    {
      "name": "Webhooks"
    }
  ],
  "paths": {
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List available models",
        "description": "Audio speech models include their full preset voice catalogue in capabilities.voices. Speech Lite voices include language, gender, styles, and preview metadata. Use /v1/voices/catalog for a filtered voice list.",
        "tags": [
          "Models"
        ],
        "parameters": [
          {
            "name": "mode",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "agent",
                "image",
                "video",
                "audio"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Model catalogue",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/files": {
      "post": {
        "operationId": "createFileUpload",
        "summary": "Create a presigned media upload",
        "description": "Use the returned upload_url with an HTTP PUT and the exact upload_headers, then pass url to a generation.",
        "tags": [
          "Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "content_type",
                  "size"
                ],
                "properties": {
                  "filename": {
                    "type": "string",
                    "example": "product.png"
                  },
                  "content_type": {
                    "type": "string",
                    "example": "image/png"
                  },
                  "size": {
                    "type": "integer",
                    "example": 2480123
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/generations": {
      "post": {
        "operationId": "createGeneration",
        "summary": "Create image, video, or audio",
        "tags": [
          "Generations"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGeneration"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Generation queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Generation"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "operationId": "listGenerations",
        "summary": "List API generations",
        "tags": [
          "Generations"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Generation list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/generations/{id}": {
      "get": {
        "operationId": "getGeneration",
        "summary": "Get generation status and outputs",
        "tags": [
          "Generations"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Generation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Generation"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/speech": {
      "post": {
        "operationId": "createSpeechGeneration",
        "summary": "Create multi-block speech",
        "description": "Renders up to 50 voice blocks into one audio file. Use preset ids from /v1/voices/catalog for the selected model. Speech Cloning also accepts custom voice resource ids from /v1/voices.",
        "tags": [
          "Speech"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSpeechGeneration"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Speech generation queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpeechGeneration"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/speech/{id}": {
      "get": {
        "operationId": "getSpeechGeneration",
        "summary": "Get multi-block speech status",
        "tags": [
          "Speech"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Speech generation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpeechGeneration"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "summary": "Poll any asynchronous job",
        "tags": [
          "Generations",
          "Speech",
          "Agents",
          "Personas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Generation or Agent run",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Generation"
                    },
                    {
                      "$ref": "#/components/schemas/SpeechGeneration"
                    },
                    {
                      "$ref": "#/components/schemas/AgentRun"
                    },
                    {
                      "$ref": "#/components/schemas/Persona"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/agents/runs": {
      "post": {
        "operationId": "createAgentRun",
        "summary": "Create an Agent production plan",
        "description": "Plans require explicit approval unless auto_approve is true. Planning costs one credit; approved media steps reserve their maximum authorized budget.",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAgentRun"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plan proposed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRun"
                }
              }
            }
          },
          "202": {
            "description": "Plan approved and queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRun"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "operationId": "listAgentRuns",
        "summary": "List Agent runs",
        "tags": [
          "Agents"
        ],
        "responses": {
          "200": {
            "description": "Agent runs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/agents/runs/{id}": {
      "get": {
        "operationId": "getAgentRun",
        "summary": "Get an Agent run",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Agent run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRun"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/agents/runs/{id}/approve": {
      "post": {
        "operationId": "approveAgentRun",
        "summary": "Approve an Agent plan",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "max_credits"
                ],
                "properties": {
                  "max_credits": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "plan": {
                    "type": "object",
                    "description": "Optional edited plan returned by createAgentRun."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run queued or waiting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRun"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/agents/runs/{id}/review": {
      "post": {
        "operationId": "reviewAgentRun",
        "summary": "Complete the Agent review gate",
        "tags": [
          "Agents"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "decision"
                ],
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "assemble",
                      "assets_only"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRun"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/voices": {
      "post": {
        "operationId": "createVoice",
        "summary": "Clone or design a voice",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVoice"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Voice created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voice"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "operationId": "listVoices",
        "summary": "List custom voices",
        "tags": [
          "Voices"
        ],
        "responses": {
          "200": {
            "description": "Voice list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/voices/catalog": {
      "get": {
        "operationId": "listPresetVoices",
        "summary": "List language-specific preset voices",
        "description": "Requires voices:read. Returns the complete preset catalogue without pagination, defaulting to Speech Lite. Pass an id as parameters.voice in /v1/generations or blocks[].voice in /v1/speech with the same model. /v1/voices lists workspace-owned custom voices separately.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "model",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "verbatik/speech-lite",
                "fal-ai/minimax/speech-2.8-turbo"
              ],
              "default": "verbatik/speech-lite"
            }
          },
          {
            "name": "language",
            "in": "query",
            "description": "Case-insensitive locale (en-US) or base language (en).",
            "schema": {
              "type": "string",
              "example": "ro-RO"
            }
          },
          {
            "name": "gender",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "female"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Case-insensitive match against voice id or name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Preset voice catalogue",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "object",
                    "model",
                    "data"
                  ],
                  "properties": {
                    "object": {
                      "const": "list"
                    },
                    "model": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PresetVoice"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/voices/{id}": {
      "get": {
        "operationId": "getVoice",
        "summary": "Get a custom voice",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Voice",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voice"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updateVoice",
        "summary": "Rename a custom voice",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Voice updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voice"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deleteVoice",
        "summary": "Delete a custom voice",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Voice deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/personas": {
      "post": {
        "operationId": "createPersona",
        "summary": "Create a reusable visual persona",
        "tags": [
          "Personas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePersona"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload-backed persona created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "202": {
            "description": "Described persona queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "operationId": "listPersonas",
        "summary": "List personas",
        "tags": [
          "Personas"
        ],
        "responses": {
          "200": {
            "description": "Persona list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/personas/{id}": {
      "get": {
        "operationId": "getPersona",
        "summary": "Get a persona",
        "tags": [
          "Personas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Persona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "updatePersona",
        "summary": "Update a persona",
        "tags": [
          "Personas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "shared": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Persona updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deletePersona",
        "summary": "Delete a persona",
        "tags": [
          "Personas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Persona deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/credits": {
      "get": {
        "operationId": "getCreditBalance",
        "summary": "Get workspace credits",
        "tags": [
          "Billing"
        ],
        "responses": {
          "200": {
            "description": "Credit balance",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Get API usage by mode",
        "tags": [
          "Billing"
        ],
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "operationId": "createWebhook",
        "summary": "Create a signed webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhook"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook and one-time signing secret",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "operationId": "listWebhooks",
        "summary": "List webhooks",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "Webhook list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/webhooks/{id}": {
      "get": {
        "operationId": "getWebhook",
        "summary": "Get a webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "summary": "Delete a webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "summary": "List delivery attempts",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "vb_live_…"
      }
    },
    "parameters": {
      "ResourceId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Unique key for safely retrying this POST. Cached for 24 hours.",
        "schema": {
          "type": "string",
          "maxLength": 255
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Invalid or missing API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Missing scope or API entitlement",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate or concurrency limit exceeded",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "message"
            ],
            "properties": {
              "type": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              },
              "details": {}
            }
          }
        }
      },
      "List": {
        "type": "object",
        "required": [
          "object",
          "data"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {}
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "PresetVoice": {
        "type": "object",
        "required": [
          "id",
          "label"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "matthew-en-us"
          },
          "label": {
            "type": "string",
            "example": "Matthew"
          },
          "name": {
            "type": "string"
          },
          "gender": {
            "type": [
              "string",
              "null"
            ]
          },
          "language_code": {
            "type": "string",
            "example": "en-US"
          },
          "language_name": {
            "type": "string",
            "example": "English (United States)"
          },
          "is_neural": {
            "type": "boolean"
          },
          "sample_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "styles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CreateGeneration": {
        "type": "object",
        "required": [
          "mode",
          "model",
          "prompt"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio"
            ]
          },
          "model": {
            "type": "string",
            "example": "fal-ai/flux-pro/kontext/text-to-image"
          },
          "prompt": {
            "type": "string"
          },
          "persona_id": {
            "type": "string",
            "format": "uuid",
            "description": "Optional reusable persona for image/video."
          },
          "input": {
            "type": "object",
            "properties": {
              "reference_images": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "start_frame": {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "end_frame": {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "image_refs": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "video_refs": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "audio_refs": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "video": {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "character": {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "motion_video": {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "parameters": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 1,
                "maximum": 16
              },
              "size": {
                "type": "string"
              },
              "aspect_ratio": {
                "type": "string"
              },
              "quality": {
                "type": "string"
              },
              "duration": {
                "type": "string"
              },
              "resolution": {
                "type": "string"
              },
              "voice": {
                "type": "string",
                "description": "A preset id from /v1/voices/catalog for this model, or a custom voice resource id for Speech Cloning."
              },
              "speed": {
                "type": "string"
              },
              "loop": {
                "type": "boolean"
              },
              "lyrics": {
                "type": "string"
              },
              "language_boost": {
                "type": "string"
              }
            }
          },
          "delivery": {
            "type": "string",
            "enum": [
              "public_url",
              "signed_url"
            ],
            "default": "public_url"
          }
        }
      },
      "Generation": {
        "type": "object",
        "required": [
          "id",
          "object",
          "status",
          "mode",
          "model"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "generation"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "completed",
              "partially_completed",
              "failed"
            ]
          },
          "mode": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "output_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "outputs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "media_type": {
                  "type": "string"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "estimated_credits": {
            "type": "integer"
          }
        }
      },
      "CreateSpeechGeneration": {
        "type": "object",
        "required": [
          "model",
          "blocks"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "verbatik/speech-lite",
              "fal-ai/minimax/speech-2.8-turbo"
            ]
          },
          "blocks": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "object",
              "required": [
                "text"
              ],
              "properties": {
                "text": {
                  "type": "string"
                },
                "voice": {
                  "type": "string",
                  "description": "A preset id from /v1/voices/catalog for this model, or a custom voice resource id for Speech Cloning."
                }
              }
            }
          },
          "settings": {
            "type": "object",
            "properties": {
              "volume": {
                "type": "number",
                "minimum": 0.1,
                "maximum": 10,
                "default": 1
              },
              "speed": {
                "type": "number",
                "minimum": 0.5,
                "maximum": 2,
                "default": 1
              },
              "loudness_normalization": {
                "type": "boolean",
                "default": true
              },
              "text_normalization": {
                "type": "boolean",
                "default": false
              },
              "tag_compatible": {
                "type": "boolean",
                "default": true
              }
            }
          },
          "delivery": {
            "type": "string",
            "enum": [
              "public_url",
              "signed_url"
            ],
            "default": "public_url"
          }
        }
      },
      "SpeechGeneration": {
        "type": "object",
        "required": [
          "id",
          "object",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "speech_generation"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "completed",
              "failed"
            ]
          },
          "model": {
            "type": "string"
          },
          "line_count": {
            "type": "integer"
          },
          "character_count": {
            "type": "integer"
          },
          "estimated_credits": {
            "type": "integer"
          },
          "duration_seconds": {
            "type": [
              "number",
              "null"
            ]
          },
          "output": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "media_type": {
                    "type": "string"
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            ]
          }
        }
      },
      "CreateAgentRun": {
        "type": "object",
        "required": [
          "brief"
        ],
        "properties": {
          "brief": {
            "type": "string"
          },
          "source_images": {
            "type": "array",
            "maxItems": 12,
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "priority": {
            "type": "string",
            "enum": [
              "quality",
              "balanced",
              "cost",
              "speed"
            ],
            "default": "balanced"
          },
          "direction_strategy": {
            "type": "string",
            "enum": [
              "best",
              "multiple"
            ],
            "default": "best"
          },
          "auto_approve": {
            "type": "boolean",
            "default": false
          },
          "max_credits": {
            "type": "integer",
            "minimum": 1
          }
        }
      },
      "AgentRun": {
        "type": "object",
        "required": [
          "id",
          "object",
          "status",
          "plan"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "agent_run"
          },
          "status": {
            "type": "string"
          },
          "plan": {
            "type": "object"
          },
          "estimated_credits": {
            "type": "integer"
          },
          "max_credits": {
            "type": "integer"
          },
          "reserved_credits": {
            "type": "integer"
          },
          "spent_credits": {
            "type": "integer"
          },
          "auto_approval_error": {
            "type": "string",
            "description": "Present when a plan was created but the requested automatic approval could not be applied."
          },
          "outputs": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "CreateVoice": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "kind",
              "name",
              "audio_url"
            ],
            "properties": {
              "kind": {
                "const": "clone"
              },
              "name": {
                "type": "string"
              },
              "audio_url": {
                "type": "string",
                "format": "uri"
              },
              "preview_text": {
                "type": "string"
              },
              "noise_reduction": {
                "type": "boolean"
              },
              "volume_normalization": {
                "type": "boolean"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "kind",
              "name",
              "description"
            ],
            "properties": {
              "kind": {
                "const": "design"
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "preview_text": {
                "type": "string"
              }
            }
          }
        ]
      },
      "Voice": {
        "type": "object",
        "required": [
          "id",
          "object",
          "name",
          "kind"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "voice"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "clone",
              "design"
            ]
          },
          "preview_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        }
      },
      "CreatePersona": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "source",
              "name",
              "reference_images"
            ],
            "properties": {
              "source": {
                "const": "upload"
              },
              "name": {
                "type": "string"
              },
              "reference_images": {
                "type": "array",
                "minItems": 1,
                "maxItems": 5,
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "shared": {
                "type": "boolean"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "source",
              "name",
              "description"
            ],
            "properties": {
              "source": {
                "const": "describe"
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "shared": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "Persona": {
        "type": "object",
        "required": [
          "id",
          "object",
          "name",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "persona"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "ready",
              "failed"
            ]
          },
          "preview_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "reference_images": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          }
        }
      },
      "CreateWebhook": {
        "type": "object",
        "required": [
          "url",
          "events"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://"
          },
          "description": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "generation.completed",
                "generation.failed",
                "agent.review_required",
                "agent.completed",
                "agent.failed",
                "voice.created",
                "persona.ready",
                "persona.failed"
              ]
            }
          }
        }
      }
    }
  }
}
