Verbatik LogoVerbatik
Developer API

API endpoint reference

Operations and schemas generated from the current Verbatik API definition.

Base URL: https://app.verbatik.com/api/v1. Authenticate with a workspace Bearer key.

Open interactive reference · Download OpenAPI 3.1 · Live schema

This checked-in reference is generated from the app API definition. The linked live reference reflects the deployed application. Use the guides for workflow details, including runtime validation and credit behavior.

Operations

MethodPathPurposeRequired scope
GET/modelsList available modelsmodels:read
POST/filesCreate a presigned media uploadfiles:write
POST/generationsCreate image, video, or audiogenerations:write
GET/generationsList API generationsgenerations:read
GET/generations/{id}Get generation status and outputsgenerations:read
POST/speechCreate multi-block speechgenerations:write
GET/speech/{id}Get multi-block speech statusgenerations:read
GET/jobs/{id}Poll any asynchronous jobSee guide
POST/agents/runsCreate an Agent production planagents:write
GET/agents/runsList Agent runsagents:read
GET/agents/runs/{id}Get an Agent runagents:read
POST/agents/runs/{id}/approveApprove an Agent planagents:write
POST/agents/runs/{id}/reviewComplete the Agent review gateagents:write
POST/voicesClone or design a voicevoices:write
GET/voicesList custom voicesvoices:read
GET/voices/catalogList language-specific preset voicesvoices:read
GET/voices/{id}Get a custom voicevoices:read
PATCH/voices/{id}Rename a custom voicevoices:write
DELETE/voices/{id}Delete a custom voicevoices:write
POST/personasCreate a reusable visual personapersonas:write
GET/personasList personaspersonas:read
GET/personas/{id}Get a personapersonas:read
PATCH/personas/{id}Update a personapersonas:write
DELETE/personas/{id}Delete a personapersonas:write
GET/creditsGet workspace creditscredits:read
GET/usageGet API usage by modeusage:read
POST/webhooksCreate a signed webhookwebhooks:write
GET/webhooksList webhookswebhooks:read
GET/webhooks/{id}Get a webhookwebhooks:read
DELETE/webhooks/{id}Delete a webhookwebhooks:write
GET/webhooks/{id}/deliveriesList delivery attemptswebhooks:read

Request and response details

All request and response schemas, field constraints, and reusable components are included in the OpenAPI download. The summaries below identify documented success and error responses; runtime checks may return additional errors described in troubleshooting.

GET /models

List available models.

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.

Parameters:

  • mode (query, optional).
StatusDescription
200Model catalogue
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

POST /files

Create a presigned media upload.

Use the returned upload_url with an HTTP PUT and the exact upload_headers, then pass url to a generation.

Request 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
    }
  }
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
201Upload created
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

POST /generations

Create image, video, or audio.

Request schema:

{
  "$ref": "#/components/schemas/CreateGeneration"
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
202Generation queued
400Invalid request
401Invalid or missing API key
402Insufficient credits
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /generations

List API generations.

Parameters:

  • limit (query, optional).
  • cursor (query, optional).
StatusDescription
200Generation list
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /generations/{id}

Get generation status and outputs.

Parameters:

  • id (path, required).
StatusDescription
200Generation
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
404Resource not found
429Rate or concurrency limit exceeded

POST /speech

Create multi-block speech.

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.

Request schema:

{
  "$ref": "#/components/schemas/CreateSpeechGeneration"
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
202Speech generation queued
400Invalid request
401Invalid or missing API key
402Insufficient credits
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /speech/{id}

Get multi-block speech status.

Parameters:

  • id (path, required).
StatusDescription
200Speech generation
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
404Resource not found
429Rate or concurrency limit exceeded

GET /jobs/{id}

Poll any asynchronous job.

Parameters:

  • id (path, required).
StatusDescription
200Generation or Agent run
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
404Resource not found
429Rate or concurrency limit exceeded

POST /agents/runs

Create an Agent production plan.

Plans require explicit approval unless auto_approve is true. Planning costs one credit; approved media steps reserve their maximum authorized budget.

Request schema:

{
  "$ref": "#/components/schemas/CreateAgentRun"
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
201Plan proposed
202Plan approved and queued
400Invalid request
401Invalid or missing API key
402Insufficient credits
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /agents/runs

List Agent runs.

StatusDescription
200Agent runs
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /agents/runs/{id}

Get an Agent run.

Parameters:

  • id (path, required).
StatusDescription
200Agent run
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
404Resource not found
429Rate or concurrency limit exceeded

POST /agents/runs/{id}/approve

Approve an Agent plan.

Request schema:

{
  "type": "object",
  "required": [
    "max_credits"
  ],
  "properties": {
    "max_credits": {
      "type": "integer",
      "minimum": 1
    },
    "plan": {
      "type": "object",
      "description": "Optional edited plan returned by createAgentRun."
    }
  }
}

Parameters:

  • id (path, required).
  • Idempotency-Key (header, optional).
StatusDescription
202Run queued or waiting
400Invalid request
401Invalid or missing API key
402Insufficient credits
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

POST /agents/runs/{id}/review

Complete the Agent review gate.

Request schema:

{
  "type": "object",
  "required": [
    "decision"
  ],
  "properties": {
    "decision": {
      "type": "string",
      "enum": [
        "assemble",
        "assets_only"
      ]
    }
  }
}

Parameters:

  • id (path, required).
  • Idempotency-Key (header, optional).
StatusDescription
200Completed run
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

POST /voices

Clone or design a voice.

Request schema:

{
  "$ref": "#/components/schemas/CreateVoice"
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
201Voice created
400Invalid request
401Invalid or missing API key
402Insufficient credits
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /voices

List custom voices.

StatusDescription
200Voice list
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /voices/catalog

List language-specific preset voices.

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.

Parameters:

  • model (query, optional).
  • language (query, optional).
  • gender (query, optional).
  • search (query, optional).
StatusDescription
200Preset voice catalogue
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /voices/{id}

Get a custom voice.

Parameters:

  • id (path, required).
StatusDescription
200Voice
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

PATCH /voices/{id}

Rename a custom voice.

Request schema:

{
  "type": "object",
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string"
    }
  }
}

Parameters:

  • id (path, required).
StatusDescription
200Voice updated
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

DELETE /voices/{id}

Delete a custom voice.

Parameters:

  • id (path, required).
StatusDescription
200Voice deleted
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

POST /personas

Create a reusable visual persona.

Request schema:

{
  "$ref": "#/components/schemas/CreatePersona"
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
201Upload-backed persona created
202Described persona queued
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /personas

List personas.

StatusDescription
200Persona list
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /personas/{id}

Get a persona.

Parameters:

  • id (path, required).
StatusDescription
200Persona
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

PATCH /personas/{id}

Update a persona.

Request schema:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "shared": {
      "type": "boolean"
    }
  }
}

Parameters:

  • id (path, required).
StatusDescription
200Persona updated
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

DELETE /personas/{id}

Delete a persona.

Parameters:

  • id (path, required).
StatusDescription
200Persona deleted
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /credits

Get workspace credits.

StatusDescription
200Credit balance
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /usage

Get API usage by mode.

Parameters:

  • since (query, optional).
StatusDescription
200Usage summary
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

POST /webhooks

Create a signed webhook.

Request schema:

{
  "$ref": "#/components/schemas/CreateWebhook"
}

Parameters:

  • Idempotency-Key (header, optional).
StatusDescription
201Webhook and one-time signing secret
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /webhooks

List webhooks.

StatusDescription
200Webhook list
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /webhooks/{id}

Get a webhook.

Parameters:

  • id (path, required).
StatusDescription
200Webhook
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

DELETE /webhooks/{id}

Delete a webhook.

Parameters:

  • id (path, required).
StatusDescription
200Webhook deleted
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

GET /webhooks/{id}/deliveries

List delivery attempts.

Parameters:

  • id (path, required).
StatusDescription
200Delivery list
400Invalid request
401Invalid or missing API key
403Missing scope or API entitlement
429Rate or concurrency limit exceeded

Reusable request 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"
        ]
      }
    }
  }
}