Sync MCP Server
OfficialConnects an AI agent to sync.'s lip-sync, dubbing, voice and media API so it can create, quote, track and manage video generations in chat.
Lip sync — create a lipsync video from a video/image plus audio, a script and a voice, or public URLs (
lipsync_create), and timeline lipsync of one video across multiple audio clips and ranges (lipsync_create-timeline).Translation and dubbing — translate a saved video and lip-sync it into another language (
dubbing_create), list supported languages (dubbing_get-options), and produce translated-audio previews with cost estimates.Speech and voices — synthesize a scripted voice preview and list premade or cloned voices (voice cloning and deletes are admin-only).
Edit Dialogue — transcribe a single-speaker video, apply user-approved word changes/removals as an audio preview, then render the final lip-synced video.
Cost control — quote lip-sync, dubbing and dialogue renders before spending (
generations_estimate-cost,dialogue-videos_estimate,translation-previews_estimate) and read actual past costs per component.Generation tracking — read, list, wait on, or fetch continuation inputs for generations, including signed output URLs and error codes.
Bulk work — start up to 50 independent jobs in one call (
jobs_create-many) and follow them together (jobs_get-many), or submit large queued batches (20–500 items) on eligible plans.Assets — import YouTube/TikTok/Instagram/Facebook links or URLs, get upload URLs for local files, list/count/get/update assets, fetch download links and playback metadata (fps, frames, dimensions).
Audio prep — trim an audio asset to a shorter first-N-seconds copy.
Projects — create, read, list, rename projects and read a project's generation history.
Account and organizations — see who is signed in, plan, limits and feature flags, check credits/usage, and list or switch organizations.
Transcription and speaker analysis — word-level transcription, speaker-to-face matching, and per-clip face tracks for timeline lipsync.
Feedback — report confusing errors, bugs or missing capabilities to the sync. team.
Provides voice capabilities through ElevenLabs: listing premade and cloned voices, cloning custom voices from an audio or video sample, deleting cloned voices, and synthesizing speech from text with configurable voice stability and similarity boost. These voices can drive lipsync generations (script + voiceId) or be used to produce standalone speech audio.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Sync MCP ServerCreate a lipsync video from video URL and audio URL using lipsync-2"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
sync. MCP server
Connect your AI agent to sync. to lip-sync videos, translate and dub them into other languages, clone voices, and manage assets and projects from a chat or a coding session.
sync. hosts this server at https://mcp.sync.so/mcp. You sign in with your
sync. account, so there is nothing to install and no API key to copy. Every merge
to this repository's main deploys there.
Connect your agent
ChatGPT
Open sync. in ChatGPT and connect your account. In ChatGPT, sync. Studio also opens inside the chat.
Claude (claude.ai and Claude Desktop)
Open Settings → Connectors and choose Add custom connector.
Name it
sync.and set the URL tohttps://mcp.sync.so/mcp.Click Connect and sign in to sync.
Claude Code
claude mcp add --transport http sync https://mcp.sync.so/mcpThen run /mcp in Claude Code, select sync and sign in. Add --scope user to
use it in every project.
Codex
codex mcp add sync --url https://mcp.sync.so/mcp
codex mcp login syncCursor
Add to .cursor/mcp.json in a project, or ~/.cursor/mcp.json for all projects:
{
"mcpServers": {
"sync": { "url": "https://mcp.sync.so/mcp" }
}
}Cursor asks you to sign in to sync. the first time it connects.
VS Code
Add to .vscode/mcp.json:
{
"servers": {
"sync": { "type": "http", "url": "https://mcp.sync.so/mcp" }
}
}Other clients
Any client that supports remote MCP servers over Streamable HTTP with OAuth can
use https://mcp.sync.so/mcp. The client registers itself, and you sign in to
sync. in the browser.
The server is listed in the official MCP Registry
as io.github.synchronicity-labs/mcp-server, so clients and directories that read
the registry can find and add it. server.json is that listing.
Local server with an API key
For clients without remote MCP support, and for scripts and CI, run the server locally over stdio with a sync. API key:
claude mcp add sync -e SYNC_API_KEY=your-api-key -- npx -y @sync.so/mcp-server@latestOr in a client's JSON config:
{
"mcpServers": {
"sync": {
"command": "npx",
"args": ["-y", "@sync.so/mcp-server@latest"],
"env": { "SYNC_API_KEY": "your-api-key" }
}
}
}Without SYNC_API_KEY, the server starts a device login on first run: visit the
URL it prints and enter the code. The token is cached at
~/.config/sync/mcp-credentials.json.
npm releases are published separately from the hosted deploy and can lag behind
it, so prefer the hosted server when your client supports it. @latest makes npx
fetch the newest release when the client restarts the server; without it, npx can
keep running an old cached copy.
Update notice
At startup a local server asks the npm registry for the latest version, at most once
a day (the answer is cached in ~/.config/sync/mcp-update-check.json). The check runs
in the background with a two-second limit and never delays startup or a tool call; if
it fails, nothing is shown. When a newer version exists, the server's instructions and
the first tool result of the session tell the agent to ask you to restart with
npx -y @sync.so/mcp-server@latest or switch to the hosted server.
To turn it off, set SYNC_MCP_UPDATE_CHECK=off or pass --no-update-check. It is
also skipped when CI is set, and the hosted server never checks.
Related MCP server: Sisif AI MCP Server
What to ask
Paste prompts like these into your agent. Asset IDs come from your sync. library. Links can be public media URLs or YouTube, TikTok, Instagram and Facebook videos.
Ask | What the agent does |
"Lipsync video asset |
|
"Lipsync https://example.com/talk.mp4 to https://example.com/voiceover.wav." |
|
"Translate https://www.youtube.com/watch?v=… to Spanish." | Imports the link with |
"Make video asset | Picks a voice with |
"How many credits do I have left?" |
|
"What did my last generation cost?" | Finds it in history and reads |
Translation, dubbing, speech previews and voice clones are quoted and confirmed with you before they start.
Agent skills
Step-by-step workflows for these tools (lipsync, talking photos, dubbing, Edit Dialogue,
campaigns, batches, troubleshooting and the API) are agent skills in
synchronicity-labs/skills. Install them
in any agent with npx skills add synchronicity-labs/skills. The ChatGPT and Codex
plugin ships them from a pinned commit of that repository; see
docs/chatgpt-plugin.md.
Tools
The hosted server exposes a curated set of tools to every client:
Area | Tools |
Lip sync |
|
Translation and dubbing |
|
Speech and voices |
|
Edit Dialogue |
|
Assets |
|
Projects |
|
Many jobs |
|
Batches |
|
Account |
|
¹ Not offered to the ChatGPT app, whose embedded Studio has no timeline.
² Not in the ChatGPT app listing yet. jobs_create-many starts up to 50 independent jobs
at once, such as one video dubbed into several languages, by running one create tool
(lipsync_create, dubbing_create, dialogue-videos_create and others) once per item,
with the same API, limits and billing as single calls on any plan; jobs_get-many follows
the set. See Jobs. A batch is the API's separate queued
pipeline for large runs (20 to 500 generations) on Scale plans and above that can wait
hours. Where the account's plan doesn't include batch, the API answers 402 with
requiredPlan and billingUrl, which the tools pass on.
Organizations with the matching feature also get scenes_detect (camera cuts in a
video) and stems_separate (vocals and background audio), outside the ChatGPT
app. They are in the lipsync and assets toolsets locally.
Clients with app support also get the tools behind the embedded Studio app:
Studio views and drafts, the upload widget and app helpers. Those are clients
whose MCP handshake name selects the ChatGPT or Codex app profile (openai-mcp,
openai-mcp (Codex); see src/client-profile.ts). Other clients don't see these
tools, and their calls to them are refused.
Local toolsets
The local stdio server can also offer a tool for every other public API operation in
the OpenAPI spec, 65+ in all. By default it lists the
hosted set above, without its admin tools (assets_delete and voices_clone),
plus jobs_get, jobs_wait and the transcriptions_* tools, whose speaker face
tracks feed lipsync_create-timeline clips.
To list more, set SYNC_MCP_TOOLSETS or pass --toolsets with a comma-separated list:
Toolset | Adds |
| The default above, so |
| Lip sync, timeline, Edit Dialogue, audio trim and batch tools, plus raw |
| Translation and dubbing tools, and the batch tools |
|
|
|
|
|
|
|
|
| Every delete ( |
| Every tool, as before this option existed |
Job, account and generation reads (jobs_get, jobs_wait, jobs_get-many,
generations_get, account_get-context, organizations_list, organizations_select and
similar) come with every selection, as does jobs_create-many whenever a create tool it
runs is listed. Naming toolsets replaces
the default rather than adding to it. To get every tool back:
claude mcp add sync -e SYNC_API_KEY=your-api-key -e SYNC_MCP_TOOLSETS=all -- npx -y @sync.so/mcp-server@latestUnless it lists everything, the server's instructions tell the agent which toolsets are listed and how to get the rest, so it can ask you to restart the server with a wider set. The hosted server ignores this setting.
Tool workflows describes how the multi-step and paid tools behave.
Tool names follow one <noun>_<verb> scheme (lipsync_create, generations_get).
The names used before it (create-lipsync, generate_get-generation) still work for a
deprecation period: calls through them run the same tool and add a one-line notice
naming the new one. Tool names has the full old → new table.
CLI Options
Usage: sync-mcp [options]
Options:
--api-key <key> API key (or set SYNC_API_KEY env var)
--base-url <url> API base URL (default: https://api.sync.so)
--transport <type> stdio (default) or http
--port <port> HTTP port (default: 3002, only with --transport http)
--no-spend-confirmation
Unattended automation: drop the cost-quote and confirm-before-paying
instructions (or set SYNC_MCP_SPEND_CONFIRMATION=off)
--no-update-check Skip the daily npm check for a newer version (or set
SYNC_MCP_UPDATE_CHECK=off; skipped when CI is set)
--toolsets <list> stdio only: comma-separated tools to list (or set SYNC_MCP_TOOLSETS):
default, lipsync, dubbing, assets, projects, transcription,
voices, admin or all (default: the hosted set without admin)
-h, --help Show this help messageUnattended automation
By default the tools tell the agent to quote a paid action and wait for the user's
approval. When the server runs a pipeline or a scheduled agent whose operator has already
approved spending, start it with --no-spend-confirmation (or
SYNC_MCP_SPEND_CONFIRMATION=off). The agent then creates jobs without quoting or asking,
and estimate tools stay available. Agents cannot change this setting.
Job tools take wait: true to wait on the server (up to about 50 seconds per call, with
progress notifications when the client sends a progressToken): generations_get,
translation-previews_get, transcriptions_get and social imports
through assets_create. On the local server, jobs_wait and jobs_get do the same for
every kind of job (generation, transcription, speaker analysis, translation preview,
import) with one input, {kind, id, projectId?}, and one result shape and status set;
see Jobs. jobs_get-many reads up to 50 jobs that way at once, on both
servers.
When the API offers it, feedback_send lets agents report confusing errors, wrong results
and missing capabilities to the Sync team.
Environment variables and the HTTP server's session, memory, upload and diagnostics limits are in HTTP server configuration.
How It Works
At startup, the server fetches the public OpenAPI spec from
{baseUrl}/api-jsonand turns each operation into an MCP tool with a Zod input schema.Hand-written tools add multi-step workflows on the same API, such as translate and dub, Edit Dialogue, speech previews and cost lookups.
Each tool call is an authenticated request to the sync. API, with your OAuth token (hosted) or API key (local).
Over stdio, a new public API operation becomes a tool on the next restart. The hosted server only exposes tools on its allowlist, so a new hosted tool ships with a release of this repository.
Programmatic Usage
You can also use the server as a library:
import { createSyncMcpServer, resolveConfig } from '@sync.so/mcp-server';
const config = resolveConfig({ apiKey: 'your-key' });
const server = await createSyncMcpServer(config);Development
HTTPS source tests use the local openssl command to create a one-day, self-signed
test identity. Temporary certificate and key files are removed before the tests run.
# Install dependencies
pnpm install
# Build
pnpm run build
# Run tests
pnpm test
# Lint
pnpm run lint
# Type check
pnpm run typecheck
# Script tests (monitor, smoke check, pre-commit size check)
pnpm run test:scriptsDevelopment needs Node 26 or newer (.nvmrc); devEngines in package.json
enforces it on install. pnpm install installs a pre-commit hook. It runs Oxlint and Oxfmt on staged
files, and blocks a staged source file that grows past 5,000 tokens (20,000
bytes). Files already over that size are exempt until someone splits them.
Local HTTP Transport Testing
To test the HTTP transport (OAuth flow) locally:
Copy
.env.exampleto.envand fill in the valuesStart a tunnel to expose localhost:
ngrok http 3002Update
MCP_ISSUER_URLin.envwith the ngrok URLStart the server:
source .env node dist/cli.js --transport http --base-url $SYNC_BASE_URL --port 3002Verify it works:
curl https://<ngrok-url>/health curl https://<ngrok-url>/.well-known/oauth-authorization-server
When an isolated Studio login requires the same-origin web proxy, set
SYNC_OAUTH_AUTHORIZATION_URL to its /api-proxy/v2/oauth/authorize URL, while
keeping SYNC_BASE_URL on the direct isolated API listener. Only browser
navigation uses the web proxy. Registration, code exchange, refresh, revocation,
userinfo and tool calls use the direct API and retain existing deadlines,
PKCE and confidential-client checks. The optional URL must use HTTP(S), with no
credentials, query or fragment. Existing deployments need no new setting.
Add
https://<ngrok-url>/mcpas a custom connector in Claude Web
Learn More
Tool workflows — How multi-step and paid tools behave
HTTP server configuration — Environment variables and runtime limits
Maintainer notes — Hosted compatibility, cancellation, OAuth proxy, uploads and monitoring
Claude directory readiness — Review checklist and remaining submission work
Sync Documentation — Full API reference and guides
Sync API Reference — Endpoint documentation
MCP Protocol — Learn about the Model Context Protocol
Sync Website — Sign up and get started
License
MIT
Available Tools
57 toolsaccount_get-contextread connected sync accountARead-onlyIdempotentInspect
Read who is signed in and which sync. organization this session runs in (paid work is created and billed there), with its plan, generation limits, feature flags, and team seat and voice-clone limits. Use it to name the organization before paid work or to check limits before planning a job; for credits, balance or spend use account_get-usage, and to list or switch organizations use organizations_list or organizations_select. account is null with an API key. limits, plan, generationLimits and features are omitted when their lookup fails, while an expired sign-in returns an error. organizationChoice says whether the organization came from organizations_select or the credential's default, and how to switch; capabilities lists optional features this MCP server has enabled, such as audioTrimming or studioDraftSync. Grants no permissions and changes no organization.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, and the description adds real operational context beyond them: account is null under an API key, limits/plan/generationLimits/features are omitted when lookup fails, and an expired sign-in raises an error. It also explains organizationChoice provenance and the capabilities field, and closes by confirming it grants no permissions and mutates nothing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The paragraph is front-loaded with purpose, then usage routing, then failure modes, which is the right order for an agent. It is dense and long for a zero-parameter read, and the closing restatement of the no-side-effects guarantee partly duplicates the readOnly/destructive annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read with an output schema, the description covers everything an agent needs: when to call it, what it returns, which fields may be absent, and how failures surface. Nothing material is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero input parameters there is nothing for the description to disambiguate, so the baseline applies. It instead spends its detail on response-field semantics (organizationChoice, capabilities, omitted-on-failure fields), which is useful but belongs to the output side rather than parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete verb and resource: "Read who is signed in and which sync. organization this session runs in," then enumerates the payload (plan, generation limits, feature flags, team seat and voice-clone limits). It explicitly separates itself from account_get-usage and organizations_list/organizations_select, so an agent can distinguish it from siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the two motivating cases ("name the organization before paid work," "check limits before planning a job") and routes the agent elsewhere for credits/balance/spend and for listing or switching organizations. Both the when-to-use and the when-not-to-use alternatives are named explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
account_get-usageread sync usage and balanceARead-onlyIdempotentInspect
Read what the connected sync. organization has left to spend in the current billing period. Which section is filled depends on how it is billed: credits gives balance, available (spendable now) and inFlight (held by running jobs); freeMonthlyLimits gives generations and text-to-speech used and max, with monthlyResetDate. Only when both are null does it fill usage with the period's billed totalCostCents, totalFrames and totalTtsSeconds, and usage stays null if the API reports those totals as incomplete. canManageBilling is true only when billing allows it and the caller is an owner or admin. Not for what one past generation cost (generations_get-costs, when available), a quote for new work (generations_estimate-cost), or plan limits and organization (account_get-context). Buys no credits, changes no plan and starts no generation.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description goes well beyond them by explaining the polymorphic response: credits when credit-billed, freeMonthlyLimits when free-tier, usage only when both are null and only when totals are not reported as incomplete. It also discloses the authorization rule for canManageBilling (billing must allow it and caller must be owner or admin), which is behavior an agent cannot get from the schema. Nothing here contradicts the readOnlyHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the primary purpose, then the response-shape rules, then a compact 'not for' list. Dense but every clause carries information an agent needs, since the output schema alone does not tell you which branch is populated. It is long for a zero-parameter read, and the conditional-field sentence is packed tightly enough that it requires careful reading.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be enumerated, yet the description supplies the missing interpretive layer: which of credits/freeMonthlyLimits/usage is populated under which billing mode and when usage stays null. For a zero-param read with rich conditional output, this is exactly the context needed to interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters (additionalProperties: false, empty properties), so there is no parameter meaning to add and the baseline of 4 applies. The description compensates by describing how the response shape varies, which is the only input-adjacent ambiguity (which billing mode the org is in).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read what the connected sync. organization has left to spend in the current billing period') and immediately distinguishes itself from three named siblings with different scope. An agent can tell this apart from account_get-context or generations_get-costs without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Contains an explicit exclusion block naming the alternative for each adjacent need: past generation cost → generations_get-costs, new-work quote → generations_estimate-cost, plan limits and org → account_get-context. It also closes off side-effect expectations (buys no credits, changes no plan, starts no generation), leaving nothing to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_countcount assetsARead-onlyInspect
Count the assets you can access in the current organization that match projectId, userId, searchQuery and types, the same filters as assets_list; filters combine, and deleted assets are not counted. Use it when you only need how many; use assets_list to see, pick or page through assets. Returns a bare number, not asset records. Omit sortBy, limit and cursor: they do not change the count, but they are still validated, so a limit outside 1 to 100 fails the call.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | No effect on the count; omit it. If sent, it must be an integer from 1 to 100 or the call fails validation. | |
| types | No | Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list; an asset of any listed type matches. | |
| cursor | No | No effect on the count; omit it. | |
| sortBy | No | No effect on the count; omit it. | |
| userId | No | Only assets created by this user: a user UUID. | |
| projectId | No | Only assets attached to this project: a project UUID from projects_list or projects_create. | |
| searchQuery | No | Case-insensitive text matched anywhere in the asset name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish a safe read operation, but the description adds real behavioral context: deleted assets are excluded from the count, filters combine conjunctively, and passing a limit outside 1-100 causes a validation failure. That last point is a genuine trap the annotations don't reveal. It doesn't discuss permission scoping beyond 'you can access', which keeps it just under a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then the alternative, then the return type and the parameter trap. Nothing is wasted and the ordering mirrors what an agent needs to decide before calling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by saying it returns a bare number rather than records. All seven parameters are documented in the schema, no parameters are required, and the description covers the non-obvious validated-but-ignored behavior, so an agent can call this correctly without further inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds the combination rule (multiple filters AND together) and the no-effect/validated distinction for sortBy, limit and cursor, which the schema states per-parameter but never as a coherent rule. That is useful meaning beyond the schema's field-by-field text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ('Count the assets you can access in the current organization') and scopes it to the same filter set as assets_list. It states the return type ('a bare number, not asset records'), which removes any ambiguity about whether this is a listing tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes between the two siblings: 'Use it when you only need how many; use assets_list to see, pick or page through assets.' It also gives a when-not rule for pagination/sort parameters, warning that they are validated even though they have no effect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_createregister a media assetADestructiveInspect
Register a media file at a URL as a reusable sync. asset, or import a YouTube, TikTok, Instagram or Facebook video link into a saved VIDEO asset. Use it for a public https:// file, the url assets_create-upload-url returned after your PUT, or a social link. Not for a local file (call assets_create-upload-url first), finding an existing asset (assets_list) or renaming one (assets_update). Returns the asset (id, type, name, url, visibility, thumbnailUrl, projectId); pass its id as an asset input to generation tools, or as videoAssetId in dubbing_create when available.
Direct URL: the asset is saved at once and every call saves another one, so do not repeat a call that succeeded. A sync. upload must already hold the PUT bytes and fit the plan's size limit (422 otherwise).
Social link: send type=VIDEO and the projectId for this request; the asset is named after the video, and name, visibility and the metadata fields are ignored. 409 import_in_progress means it is still downloading: wait retryAfterMs (15 seconds if absent) and repeat the identical request, which reuses the running import, or pass wait: true. The importJobId in the 409 is not an asset id. On import_failed, import_not_enabled, import_unavailable or an import limit (daily or concurrent), explain the error and stop; do not restart the import. Import first, then estimate and confirm translation.
Projects: pass projectId only with projectIntent=explicit, when the user asked to work in that project, selected it in the interface, or it was just created for this request. A matching workflow/name or an already-open editor is never permission to modify it. Default new work to a new project.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Media URL: a public https:// file, the url (not the uploadUrl) that assets_create-upload-url returned once the PUT finished, or a YouTube, TikTok, Instagram or Facebook video link. | |
| name | No | Display name for the asset. Not used for a social link, which is named after the video. | |
| size | No | File size in bytes, when known. For a sync. upload the stored file's measured size is used instead. | |
| type | Yes | Media type: VIDEO, AUDIO or IMAGE. Send VIDEO for a social video link; its import always saves a VIDEO asset. | |
| wait | No | Social link only: the server repeats the identical request every retryAfterMs (15 seconds if absent) until an attempt returns the saved asset or about 50 seconds pass. If no attempt got the asset, even when the import finished just after the last attempt, the call returns the 409 import_in_progress; call again with wait: true. | |
| width | No | Video or image width in pixels, when known. | |
| format | No | File format or extension, such as mp4 or wav, when known. | |
| height | No | Video or image height in pixels, when known. | |
| inputType | No | How the media was produced, such as UPLOAD or URL. Usually omitted. | |
| projectId | No | Project to attach the asset to; send it with projectIntent=explicit. Returns 422 if it is not a project you can use in this organization. | |
| visibility | No | USER (default) or ORGANIZATION, which shares the asset with everyone in the organization. A USER asset is still visible across the organization when attached to a project shared with the organization. Not used for a social link. | |
| thumbnailUrl | No | Optional preview image URL for the asset. | |
| contentSha256 | No | Optional lowercase hex SHA-256 digest of the file's bytes. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| durationSeconds | No | Media length in seconds, when known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: non-idempotency is spelled out operationally ('every call saves another one, so do not repeat a call that succeeded'), plus the 422 size-limit condition, the 409 import_in_progress retry contract with retryAfterMs fallback, and a stop-don't-retry list of terminal import errors. The warning that 'The importJobId in the 409 is not an asset id' preempts a concrete agent mistake, and nothing contradicts destructiveHint=false/idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the two-sentence purpose and the sibling exclusions, then cleanly sectioned into Direct URL / Social link / Projects blocks that map onto real decision branches. It is long, and a few clauses (e.g. the full enum of inputType behavior) could be trimmed, but almost every sentence disambiguates a genuine failure mode.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 15-parameter mutating tool with no output schema, the description supplies the return shape inline (id, type, name, url, visibility, thumbnailUrl, projectId), the follow-on usage ('pass its id as an asset input to generation tools, or as videoAssetId in dubbing_create'), and the async import contract. An agent could invoke and recover from this tool using the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3; the description earns above that by adding conditional semantics the schema only implies — that name, visibility and metadata fields are ignored for social links, and that projectId is only valid alongside projectIntent=explicit and never inferred from a matching workflow or open editor. It stops short of 5 because per-parameter detail (size, thumbnailUrl, contentSha256) is left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource pair ('Register a media file at a URL', 'import a ... video link into a saved VIDEO asset') and explicitly names what it is not for, citing the sibling tools assets_create-upload-url, assets_list and assets_update. An agent can distinguish this from every nearby asset tool without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing: local file → assets_create-upload-url first, existing asset → assets_list, rename → assets_update, social link → this tool with type=VIDEO. It also specifies the sequencing prerequisite ('Import first, then estimate and confirm translation') and the projectId/projectIntent gating rule with a default ('Default new work to a new project').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_create-upload-urlget a media upload urlADestructiveInspect
Get a presigned upload URL for a local audio, video or image file: step 1 of 2 for media that is not already at a public URL. PUT the raw bytes to the returned uploadUrl with exactly the declared Content-Type and byte size, then pass the returned url (not uploadUrl) to assets_create to register the asset; until then no asset exists. Not for a public https:// file or a social video link (pass those straight to assets_create), or for re-hosting an already saved video as an Edit Dialogue source (dialogue_upload-source, when available). Returns {uploadUrl, url, expiresIn}: expiresIn is the upload URL's lifetime in seconds; if it expires, request a new one. Spends no credits. Each call issues a new storage path behind a random prefix, so it never collides with an existing file; request a separate upload URL for each file. For example, it returns 422 when size exceeds your plan's upload limit, and assets_create returns 422 if nothing was uploaded.
| Name | Required | Description | Default |
|---|---|---|---|
| size | Yes | Exact file size as a whole number of bytes, up to 5GB; the PUT must send exactly this many bytes. Your plan's size limit is checked against it here, and again by assets_create on the uploaded file. | |
| fileName | Yes | Name of the local file with its extension, up to 255 characters. It only names the stored file: the extension is kept (lowercased), spaces become underscores and other special characters may be dropped. | |
| contentType | Yes | MIME type starting with audio/, video/ or image/, such as video/mp4; send the same value as the Content-Type header on the PUT. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only say the call is non-read-only, non-idempotent, open-world and destructive; the description supplies everything else of consequence: that nothing is registered until assets_create runs, that the returned url (not uploadUrl) is what gets passed on, that expiresIn is a lifetime in seconds after which a new URL must be requested, that no credits are spent, and that each call mints a fresh random-prefix path so it can never collide. It also discloses failure modes (422 from this tool vs 422 from assets_create when nothing was uploaded).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and the 'step 1 of 2' framing, and nearly every clause carries non-redundant information (alternatives, return fields, expiry, error codes). It is a single dense block of roughly 150 words, which is justified by the two-step workflow but costs some scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return contract itself ({uploadUrl, url, expiresIn} with each field's meaning) and adds the downstream hand-off and the 422 conditions. For a non-idempotent, non-read-only tool operating in an open-world storage flow, nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so fileName, contentType and size are already fully documented, including the 5GB bound, extension normalization and the Content-Type header requirement. The description restates the Content-Type and byte-size constraint in the PUT step but adds no new parameter semantics beyond what the schema already carries, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get a presigned upload URL for a local audio, video or image file') and immediately frames it as 'step 1 of 2' of a named workflow, so an agent knows exactly what it produces and that no asset exists yet. It also draws the boundary against assets_create and dialogue_upload-source in the same paragraph, which is stronger differentiation than most siblings in this list provide.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the when-not cases: not for a public https:// file or social video link (pass those straight to assets_create) and not for re-hosting an already saved video as an Edit Dialogue source (use dialogue_upload-source). It also gives the positive condition — local file, one upload URL per file — so both branches of the decision are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_getget an assetARead-onlyInspect
Get one asset you can access in the current organization by its id: type, name, media url, durationSeconds, size in bytes, format, width, height, visibility, createdAt, thumbnailUrl and proxyPath (a browser playback proxy, null unless one was generated). Use it when you already hold an id; to find one by name, type or project use assets_list, for a signed download link use assets_get-download-url, and for fps, frame count or codec use assets_get-playback-metadata. Returns 404 asset not found for a deleted id, another organization's asset or one you cannot see. Previews: show only that asset's exact thumbnailUrl (query string intact), never a searched, generated or guessed image, another asset, a stock image, a voice portrait, or the asset's url or proxyPath. If thumbnailUrl is missing or fails to load, show https://mcp.sync.so/asset-placeholder.svg labeled "Thumbnail unavailable" (a placeholder, not a frame from the asset), or only that label if the host cannot display it. Playback still uses the media url.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Asset id (UUID) from assets_list, or the id assets_create returned; a generation or project id returns 404. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, non-destructive, closed-world), and the description still adds real behavior: 404 semantics for deleted or cross-organization ids, proxyPath being null unless generated, and a mandated rendering fallback when thumbnailUrl is missing. That is materially more than the annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then alternatives, then error behavior, then display policy — a sensible ordering. The preview paragraph is long and somewhat repetitive (restating what must NOT be shown in several ways), costing a point on tightness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by enumerating the returned fields (type, name, media url, durationSeconds, size, format, dimensions, visibility, timestamps, thumbnailUrl, proxyPath). Combined with 404 semantics and the null-handling note, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'id' parameter is already documented in the schema, including the note that generation or project ids return 404. The description restates the same constraint ('by its id') without adding format or sourcing detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (get one asset) plus the exact scope ('in the current organization by its id') and enumerates the returned fields. It explicitly separates itself from assets_list, assets_get-download-url and assets_get-playback-metadata, so an agent can pick it without opening sibling schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit precondition ('Use it when you already hold an id') and routes to alternatives for the other intents: assets_list for lookup by name/type/project, assets_get-download-url for signed links, assets_get-playback-metadata for fps/frame count/codec. It also names the failure cases (deleted id, other organization, no visibility) that should not be retried here.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_get-download-urlget an asset download urlARead-onlyInspect
Get a download link for one asset's original media file, by id. Use it when the user wants to download or save the file; use assets_get for the asset's details and media url, and assets_get-playback-metadata for frame timing. For files in sync. storage the link is signed, valid for up to 7 days and downloads under the asset's name; an asset registered from an outside URL returns that URL unchanged. Returns the URL as a plain string, or 404 when the asset does not exist, was deleted or you cannot see it. Return the URL exactly as given, query string included, and request a fresh one instead of reusing an old link.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Asset id (UUID) from assets_list or assets_get, not a generation id; for a generation's output use its outputMediaUrl from generations_get. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld/destructive annotations: signed-link lifetime (up to 7 days), the filename behavior on download, the passthrough case for externally registered assets, and the 404 conditions including a permission-based invisibility case. It also gives operational guidance not to reuse or alter the link, which annotations could never convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then alternatives, then behavior, then return/usage rules – a sensible order. It is somewhat dense at four sentences, but each carries distinct operational information; no filler or restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description covers the return value (plain string URL), the external-URL edge case, and the 404 failure modes, plus a caution against link reuse. Nothing needed to call this single-parameter tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the id description already distinguishes asset ids from generation ids and points to outputMediaUrl. The description adds only 'by id' with no further syntax, format, or example, so it neither repeats harmfully nor compensates meaningfully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: 'Get a download link for one asset's original media file, by id.' The 'original media file' qualifier and 'by id' scoping separate it cleanly from assets_get, which returns details and a media url.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the selecting condition ('use it when the user wants to download or save the file') and names the two adjacent alternatives with their purposes: assets_get for details/media url, assets_get-playback-metadata for frame timing. An agent can route without opening other schemas.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_get-playback-metadataread video playback metadataARead-onlyIdempotentInspect
Read one asset's measured playback metadata: duration in seconds, fps, frameCount, width, height, codec, container format, proxyPath (a browser playback proxy), proxyRequested (a proxy was requested, so proxyPath may appear later) and thumbnailsManifestUrl. Use it to convert between seconds and frames for frame-accurate edits such as lipsync_create-timeline clips; use assets_get for the name and media url, and assets_get-download-url to download the file. Requires a signed-in user: with an API key it returns {supported: false, metadata: null}. metadata is null when nothing has been recorded for the asset, and a field it could not measure is null or omitted; treat those values as unknown and never guess them. It does not analyze media, read transcripts, or change the asset.
| Name | Required | Description | Default |
|---|---|---|---|
| assetId | Yes | Asset id (UUID) from assets_list or assets_get. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds real behavior the annotations cannot: the signed-in-user requirement and the exact API-key degradation payload ({supported: false, metadata: null}), plus null/omitted field semantics and an instruction never to guess unmeasured values. The only minor gap is that it does not describe pagination/caching or error behavior, but for a single-object read this is close to complete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and the returned-field list, then use case, then alternatives, then caveats — a logical progression with no filler. The long inline field enumeration is somewhat redundant given an output schema exists, which keeps it below a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only tool with an output schema and full annotation coverage, the description supplies everything an agent needs: purpose, the frame-conversion use case, sibling routing, auth/degradation behavior, and null semantics. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single assetId parameter with 100% schema description coverage (UUID, sourced from assets_list or assets_get), so the schema already carries the semantics. The description only implies single-asset scoping via 'Read one asset's' and adds no format or sourcing detail beyond the schema; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb+resource ('Read one asset's measured playback metadata') and enumerates exactly what comes back (duration, fps, frameCount, dimensions, codec, proxy fields, thumbnailsManifestUrl). It also carves itself apart from siblings assets_get and assets_get-download-url, so an agent can pick it without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete positive use case ('convert between seconds and frames for frame-accurate edits such as lipsync_create-timeline clips') and explicitly routes the agent elsewhere for name/media url (assets_get) and file download (assets_get-download-url). It also states negative scope: it does not analyze media, read transcripts, or change the asset.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_listlist assetsARead-onlyInspect
List the media assets (VIDEO, AUDIO, IMAGE) you can access in the current organization, one page at a time, to find an asset id by name, type, creator or project. Not for an id you already hold (use assets_get), a total alone (use assets_count) or generation results (use generations_list, or projects_list-generations when available). Filters combine, so an asset must match all of them; deleted assets never appear. Returns {items, nextCursor, totalCount}: each item includes id, name, type, url, durationSeconds, size, format, width, height, visibility, createdAt, thumbnailUrl and proxyPath; totalCount counts every match across pages, and nextCursor is absent on the last page. Previews: show only each item's own exact thumbnailUrl, query string intact. Never search the web, generate an image, guess or construct a URL, or substitute another asset, a stock image, a voice portrait, or the asset's url or proxyPath. If thumbnailUrl is missing or fails to load, show https://mcp.sync.so/asset-placeholder.svg labeled "Thumbnail unavailable" and say it is a placeholder, not a frame from the asset; if the host cannot display it, say "Thumbnail unavailable" without substituting an image. Playback still uses the asset's media url.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, an integer from 1 to 100 (default 10); other values fail validation. Keep it small and page with cursor. | |
| types | No | Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list; an asset of any listed type matches. | |
| cursor | No | The nextCursor from the previous page; send the same filters and sortBy with it. Omit for the first page. | |
| sortBy | No | Sort order (default nameAsc). dateAsc and dateDesc sort by creation time, kindAsc and kindDesc by file format; duration, size and kind sorts put missing values last. | |
| userId | No | Only assets created by this user: a user UUID. | |
| projectId | No | Only assets attached to this project: a project UUID from projects_list or projects_create. | |
| searchQuery | No | Case-insensitive text matched anywhere in the asset name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, but the description adds real semantics the annotations cannot: filters are AND-combined, deleted assets are never returned, totalCount spans all pages while nextCursor is absent on the last page. It also documents the item field set in lieu of an output schema. The remaining gap is minor — no note on rate limits or whether access scope varies by role.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose, exclusions and filter/pagination semantics are front-loaded and tight, but the preview block is disproportionately long and partly redundant: "Never ... substitute another asset, a stock image, a voice portrait, or the asset's url or proxyPath" is restated by the fallback sentence about a placeholder image. That content is operationally useful but could be roughly halved without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates fully by enumerating the response envelope {items, nextCursor, totalCount} and every item field, plus pagination and sort tie-breaking behavior. For a 7-parameter, zero-required list tool with annotations covering safety, nothing an agent needs to call or render results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema baseline is 3; the description earns above that by adding cross-parameter semantics absent from the schema — "Filters combine, so an asset must match all of them" — and by restating the id-lookup use case that motivates searchQuery/types/userId/projectId. It does not add format or syntax detail for the UUID parameters, so it stops short of 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List the media assets (VIDEO, AUDIO, IMAGE)") plus the scope ("you can access in the current organization") and the user goal ("find an asset id by name, type, creator or project"). It also names the siblings it is not — assets_get, assets_count, generations_list, projects_list-generations — so an agent can discriminate without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not conditions are given with the correct alternative for each: "Not for an id you already hold (use assets_get), a total alone (use assets_count) or generation results (use generations_list...)". This is the full when/when-not/alternative triad with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assets_updateupdate an assetADestructiveInspect
Change an existing asset's name or visibility, or correct its stored media metadata (durationSeconds, size, format, width, height), by id. Send only the fields the user asked to change: omitted fields keep their values and sent ones overwrite the stored values, so read the asset with assets_get first if the old values may be needed. Metadata fields rewrite the asset record, not the media file, and sync. reads the stored durationSeconds in later checks, such as the plan length limit for a link-imported video and dubbing review intervals, so send metadata only with a value you know is right. Not for adding new media (use assets_create) or renaming a project (use projects_rename when available). Every update acts as a user, so an API key with no owner gets 422. Name or visibility changes need the asset's creator or a signed-in organization admin or owner; an API key acts as a plain member, so only on assets its owner created. A metadata-only request works on any asset the caller can read, including other members' assets, so change those only on the user's explicit request. 403 means you can read the asset but may not change it; 404 means it does not exist, was deleted or is not visible to you. Returns the updated asset record, including id, name, visibility, url, the media fields, thumbnailUrl, userId, createdAt and updatedAt, but not proxyPath; use assets_get for that.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Asset id (UUID) from assets_list or assets_get. | |
| name | No | New display name; must not be empty. | |
| size | No | Corrected file size in bytes, a positive whole number. Send only a verified correction. | |
| width | No | Corrected width in pixels, a positive whole number. Send only a verified correction. | |
| format | No | Corrected file format or extension, such as mp4 or wav; must not be empty. Send only a verified correction. | |
| height | No | Corrected height in pixels, a positive whole number. Send only a verified correction. | |
| visibility | No | USER: visible to its creator, to everyone in the organization when the asset is attached to an ORGANIZATION-visible project, and to organization API keys with no owner. ORGANIZATION: visible to everyone in the organization. | |
| durationSeconds | No | Corrected media length in seconds, greater than 0. Later duration checks read this value, so send only a length you have verified. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, so the safety bar is partly cleared; the description nonetheless adds substantial context: omitted fields are preserved while sent fields overwrite, metadata rewrites the record and not the media file, downstream duration checks read durationSeconds, and 403/404/422 error meanings. The only gap is that the overwrite semantics read like a PUT-style idempotent operation while the annotation says idempotentHint=false, which is not a contradiction but is left unexplained.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, followed by the write-semantics rule, then auth, then error codes, then return shape — a sensible order. It is dense and long for a single paragraph, and the return-value inventory (including the proxyPath caveat) is somewhat padded given there is no output schema to contrast against.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation with no output schema, the description covers what changes, what is preserved, permission requirements per field group, API-key limitations, distinguishing 403 vs 404 vs 422, and the returned record's contents. An agent has everything needed to invoke it safely without further lookups.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter is already documented in the schema, and the description mostly restates that grouping (name/visibility vs. the media metadata set). It does add one piece of cross-field meaning the schema lacks: that durationSeconds is consumed later by plan-length limits and dubbing intervals, which justifies the caution not to guess. That is a modest addition over an already-complete schema, so the baseline 3 holds.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource plus the exact editable surface: name, visibility, and stored media metadata fields, all keyed by id. It explicitly distinguishes itself from assets_create (adding media), projects_rename (renaming projects), and assets_get (reading proxyPath), so an agent can route without opening sibling schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use and when-not-to-use guidance with named alternatives, plus a prerequisite workflow: read with assets_get first if old values may be needed. It also sets a consent rule ('change those only on the user's explicit request') for metadata-only edits on other members' assets, which is a real branching decision an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audio-trims_createprepare shorter audioAIdempotentInspect
Save the first durationSeconds of an authorized audio asset (assetId) as a new, reusable audio asset. Use it only when audio is longer than a lipsync can take and only its beginning is needed. Not for a partial video lipsync: there, leave the original video and draft unchanged and set options.sync_mode to cut_off on lipsync_create.
Explain and confirm the partial duration first. This prepares audio only: it never generates video, spends generation credits, or consumes a free generation. Persist one idempotencyKey before calling and reuse it with identical inputs only after an uncertain response. Failed operations require an explicit new attempt.
Returns id and status (queued, processing, completed or failed) at once; assetId and durationSeconds stay null until completed, errorCode is set on failure, and retryAfterMs is the wait in milliseconds before the next read. Poll audio-trims_get until completed (jobs_get and jobs_wait do not read trims), then use its assetId and actual duration for a fresh quote.
Pass assetId, not its deprecated alias audioAssetId; the call fails when neither is given or the two name different assets. projectId saves the new asset in that project and needs projectIntent=explicit, which only an explicit user choice or a project just created for this request allows.
| Name | Required | Description | Default |
|---|---|---|---|
| assetId | No | Saved AUDIO asset to shorten, from assets_list or assets_create. Required in practice; audioAssetId is only its deprecated alias. | |
| projectId | No | Project to save the shortened audio in, from projects_create or projects_list. | |
| audioAssetId | No | Deprecated alias of assetId. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | Yes | A new UUID saved before the call. Reuse it with identical input only to recover an uncertain response. | |
| durationSeconds | Yes | Seconds to keep from the start of the audio, up to 3600. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it declares the operation never generates video, spends credits, or consumes a free generation, and it specifies idempotency semantics (persist the key first, reuse only after an uncertain response, new attempt after failure). The annotations say idempotentHint=true and readOnlyHint=false; the description explains how to realize that idempotency, which the annotation cannot.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then usage, then behavior, then parameter rules, in a logical order that lets an agent stop reading early. It is long and restates a few schema facts (assetId/audioAssetId aliasing, the 3600 cap is left to the schema), so a little overlap keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating job-creating tool it covers what an agent needs: confirmation of the partial duration before calling, idempotency recovery, the poll target, and the follow-up step of re-quoting with the actual duration. Because an output schema exists, it correctly avoids restating the full return shape, mentioning only the state semantics (null until completed, errorCode, retryAfterMs).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds rule-level meaning: pass assetId rather than the deprecated audioAssetId, the call fails when neither is present or the two disagree, and projectId requires projectIntent=explicit which is only allowed for an explicit user choice or a newly created project. That paves the semantic cliff the schema alone only states tersely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Save the first durationSeconds of an authorized audio asset (assetId) as a new, reusable audio asset" gives a precise verb, resource, and output. It also scopes itself against siblings by naming lipsync_create and distinguishing the audio-only trim from the cut_off sync mode path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the positive condition (audio longer than lipsync can take and only its beginning is needed) and the exclusion with a concrete alternative (partial video lipsync → leave video and draft unchanged, set options.sync_mode to cut_off on lipsync_create). It also routes polling to audio-trims_get and explicitly says jobs_get and jobs_wait do not read trims, closing the most likely wrong-path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audio-trims_getread audio preparationARead-onlyIdempotentInspect
Read one audio trim by the id audio-trims_create returned, to follow it until it ends; jobs_get and jobs_wait do not read audio trims. Returns its status; once completed, the assetId (the same value as this id) and actual durationSeconds of the new shortened audio asset, both null before; once failed, its errorCode; and retryAfterMs, the wait before the next read.
While it is queued or processing, call again after retryAfterMs milliseconds; never create another trim. When completed, use the new assetId and its actual duration in place of the original audio. If it failed, tell the user the errorCode; another trim needs an explicit new attempt with audio-trims_create. An API error returns {error: {message, status, code when given}} instead. It never starts video generation or spends credits.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The id that audio-trims_create returned (a UUID). Poll with this same id until the trim is completed or failed. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description goes well beyond them: it discloses the retryAfterMs pacing contract, the null-before-completion field semantics, the errorCode on failure, the {error: {message, status, code}} shape for API errors, and that it never starts video generation or spends credits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the sibling exclusion, then a procedural paragraph that maps one-to-one onto agent decisions. Some return-field enumeration duplicates the output schema and could be trimmed, but every sentence carries an actionable instruction rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter async polling tool with an output schema, the description covers origin of the id, polling cadence, terminal states, failure handling, error envelope, and side-effect boundaries. Nothing an agent needs in order to call it correctly and act on the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the id semantics are already documented; the description reinforces rather than adds new syntax. It does add meaningful usage semantics for the parameter — reuse the same id across polls until completed or failed — which is slightly more than the schema's own wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Read one audio trim") plus the id provenance, and explicitly rules out sibling tools: "jobs_get and jobs_wait do not read audio trims." An agent can distinguish it from audio-trims_create and the generic jobs pollers without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use behavior: poll again after retryAfterMs while queued/processing, never create another trim, and on failure escalate to an explicit new audio-trims_create attempt. It also names the alternatives (jobs_get, jobs_wait) and states what to do with each outcome, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batches_createcreate a batch of generationsAInspect
Submit many independent lipsync generations at once as one Sync batch, such as localizing one campaign video into many languages or syncing many videos to their own audio. Each item is one /v2/generate body; Sync queues them, so they skip the per-generation concurrency limit, and results can take up to a day. Batch is a separate queued pipeline, built for large runs (20 to 500) on Scale plans and above that can wait hours; below Scale every row still takes a concurrent generation slot. For 2 or more independent jobs that should start now, on any plan, use jobs_create-many when available; when one result feeds the next, call lipsync_create or dubbing_create per video. Call with dryRun: true first to have the API check every item without creating anything. This is a paid action: every item is billed as its own generation. Before creating, estimate a representative item with generations_estimate-cost, tell the user the item count and the estimated total, and wait for their confirmation. Not idempotent: each call creates a new batch, so after an uncertain response check batches_list before creating again. Leave payload.projectId out for new work; a payload with projectId needs projectIntent=explicit, which only an explicit user selection or a project just created for this request allows. Batch may not be on every plan: a 402 names requiredPlan and billingUrl. Returns the batch id and each item's requestId; then call batches_get with wait: true.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | The generations, in order; at least 20. Plans allow up to 500 per batch by default, and the whole batch must fit in 5 MB as JSONL. | |
| dryRun | No | Validate every item with the API without creating the batch or spending anything; answers status VALIDATED. | |
| webhookUrl | No | URL Sync POSTs the batch to when it finishes, signed with the organization webhook secret. | |
| projectIntent | No | Required when any payload sets projectId. Set only when the user explicitly chose that project, or it is the project just created for this request; never infer it from a matching name or an open editor. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the mutating, non-idempotent, open-world profile, and the description adds material context beyond them: queueing that bypasses the per-generation concurrency limit, results taking up to a day, plan-gated availability with a 402 carrying requiredPlan and billingUrl, and per-item billing as a paid action. The slack below Scale (each row still consumes a concurrent slot) and the 'up to a day' latency are exactly the operational traits an agent needs before invoking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and scale limits are front-loaded, then alternatives, then safety steps, then return/next-step. Every sentence carries information, though the paragraph is dense and could be split into short scannable clauses; nothing is filler, but the single block makes the dryRun and projectIntent rules easy to miss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the tool's complexity — nested array items, billing, plan gating, non-idempotency, and a downstream polling step — the description covers prerequisites, cost confirmation, recovery after an ambiguous response, and the handoff to batches_get with wait: true. An output schema exists, yet the one-line note about returned batch id and per-item requestId still usefully names the handle needed for the next call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents items, dryRun, webhookUrl, projectIntent, and organizationId, and a baseline of 3 would apply to no added meaning. The description does add cross-parameter workflow meaning: the payload.projectId / projectIntent=explicit coupling, the rule that projectId must come from explicit user selection and never inference, and the dryRun-validates-without-spending semantics that ties to the cost-confirmation guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Submit many independent lipsync generations at once as one Sync batch', and immediately names the sibling patterns it supersedes (jobs_create-many, lipsync_create, dubbing_create). An agent can distinguish this from every other generation tool in the sibling list without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use with concrete scenarios (localizing one campaign video into many languages, syncing many videos to their own audio), volume and plan thresholds (20-500, Scale and above), and named alternatives for the 2+ immediate-jobs case and for chained/sequential work. It also prescribes a dryRun-first step, a cost-estimate-and-confirm step, and a recovery path via batches_list if the response is uncertain.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batches_getread a batchARead-onlyIdempotentInspect
Read one sync. batch by id: its status, metrics and outputUrl, and once it is COMPLETED or FAILED, one results row per item (requestId, generation status, generationId, and outputMediaUrl or error). Use it to follow a batch you created; to find a batch id or check which batches are running use batches_list, and for one item's full generation details pass its generationId to generations_get.
With wait: true it polls for up to about 50 seconds until the batch finishes, sending progress notifications when the client asks for them. Reading a finished batch's result file can add up to 30 seconds more. Batches can take hours, so call again while it runs and never create the batch again.
results: failed keeps only FAILED or REJECTED rows, and none skips reading the file. If the file cannot be read (for example too large or too slow), resultsError says why and the batch fields are still current; download outputUrl or find the generations with generations_list instead.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The batch id batches_create or batches_list returned. | |
| wait | No | Poll until the batch is COMPLETED or FAILED or about 50 seconds pass, then return its latest state; reading a finished batch's result file can take up to 30 seconds more. If it is still running, call again with wait: true instead of sleeping. | |
| results | No | Once the batch finishes, which result rows to return: all (default), failed (FAILED or REJECTED only) or none. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations it discloses concrete timing behavior: wait polls ~50 seconds, reading a finished result file can add up to 30 seconds, and batches may run for hours. It also describes degradation behavior (resultsError with reason, batch fields still current) and advises downloading outputUrl or using generations_list as fallbacks.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short paragraphs, front-loaded with purpose and return shape, then polling behavior, then the results filter edge cases. Nearly every sentence carries information, though the wait/results paragraphs partly restate schema text, costing a bit of density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a polling read tool with an output schema, this covers everything an agent needs: conditional return shape, timeout semantics, retry guidance, and fallback paths when the result file cannot be read. Nothing material about correct invocation is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description still adds meaning by tying results: failed to FAILED/REJECTED rows, explaining that none skips reading the result file (a performance hint the schema omits), and pairing the 30-second read cost with finished-batch reads. Much of the wait/results wording overlaps the schema descriptions, keeping it below a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Read one sync. batch by id") and enumerates what is returned: status, metrics, outputUrl, and per-item result rows once the batch is COMPLETED or FAILED. It explicitly distinguishes itself from batches_list and generations_get, so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ("follow a batch you created"), when-to-use-an-alternative (batches_list to find an id or check running batches, generations_get for one item's full details via generationId), and a negative instruction ("never create the batch again"). It also prescribes the polling loop ("call again while it runs") rather than sleeping.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batches_listlist batchesARead-onlyIdempotentInspect
List the batches in this session's organization, each with its id, status, metrics and outputUrl. Use it to find a batch id, to check whether a batch exists after an uncertain batches_create response before creating it again, or, when batches_create reports concurrency_limit_reached, to see which batches still run. For one batch's per-item results use batches_get; for single generations use generations_list.
It never reads another organization: for a batch created with another organizationId, switch there with organizations_select first. It takes no paging or limit parameters and returns the list the API sends. status matches one value per call, so omit it to see running and finished batches together; createdAfter and createdBefore together bound a time window.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Only batches in this status. PENDING, JOBS_CREATED and PROCESSING all mean still running; COMPLETED and FAILED mean done. | |
| createdAfter | No | Only batches created after this ISO 8601 date-time, such as 2026-11-06T00:00:00Z. Set it just before an uncertain batches_create to spot that batch. | |
| createdBefore | No | Only batches created before this ISO 8601 date-time, such as 2026-11-07T00:00:00Z. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, closed-world behavior, yet the description still adds non-obvious traits: strict organization scoping with no cross-org reads, absence of paging/limit parameters, pass-through of the API's list, and single-value status matching. The only gap is that it does not hint at ordering or result-size expectations, which matters given the explicit no-pagination stance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the sibling routing come first, followed by scope and parameter semantics, so the definition is front-loaded and every sentence carries information. It is dense and slightly long for a three-parameter list call, with the second paragraph doing several jobs at once.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a filtered list tool with an output schema, everything an agent needs is present: org scope and the remedy (organizations_select), no-pagination behavior, status enum grouping, and time-window semantics. Return-field detail is deferred appropriately to the output schema while still summarized in the first line.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema: it explains that status matches one value per call and that omitting it shows running and finished batches together, and that createdAfter/createdBefore together bound a time window. That is useful operational framing rather than restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ("List the batches in this session's organization") and immediately states the returned fields (id, status, metrics, outputUrl). It explicitly separates itself from batches_get (per-item results) and generations_list (single generations), so an agent can choose without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives three concrete when-to-use triggers: finding a batch id, verifying existence after an uncertain batches_create response before retrying, and diagnosing concurrency_limit_reached. It also names the alternatives (batches_get, generations_list, organizations_select) with the condition that selects each.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue_get-optionscheck edit dialogue availabilityARead-onlyInspect
Report which Edit Dialogue features this connection supports, as three booleans { available, keyedPreview, sourceUpload }. available is true whenever the dialogue tools are listed; keyedPreview is true when dialogue-previews_create accepts an idempotencyKey (sending one when it is false fails); sourceUpload is true when dialogue_upload-source can copy a saved video into sync. storage. The answer comes from the API spec this server loaded: the call is free, sends no request and is the same for every organization, so it does not check plan, credits or project access. Call it once before the first dialogue-previews_create to decide whether to persist an idempotencyKey. Not for lipsync models (models_list) or dubbing and voice options (dubbing_get-options, speech-previews_get-options).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld=false, so the safety profile is covered; the description adds genuinely new behavior: the answer comes from the loaded API spec, no HTTP request is sent, it costs nothing, and it is identical for every organization regardless of plan, credits or project access. It also discloses the failure mode behind keyedPreview ('sending one when it is false fails'), which is exactly the kind of consequence annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Strongly front-loaded: return shape first, then the meaning of each boolean, then the operational caveats, then the exclusions. It is denser and longer than most definitions, but nearly every clause carries distinct information; a minor trim would still leave all three boolean semantics, the free/no-request note and the alternatives.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully compensates by spelling out all three returned booleans and their conditions, plus the absence of side effects and the recommended call timing. Nothing an agent needs in order to decide whether and when to invoke it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the schema baseline applies and no parameter meaning needs explaining. The description instead documents the response fields, which is the relevant semantics for a no-arg call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Report which Edit Dialogue features this connection supports', and immediately enumerates the exact return shape { available, keyedPreview, sourceUpload }. It also names what it is not (lipsync models, dubbing/voice options), so an agent can distinguish it from the neighbouring *_get-options siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger ('Call it once before the first dialogue-previews_create to decide whether to persist an idempotencyKey') plus explicit exclusions that route to named alternatives (models_list, dubbing_get-options, speech-previews_get-options). Both when-to-use and when-not-to-use are present, which is the top of the scale.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue-previews_createpreview dialogue editsADestructiveInspect
Start an Edit Dialogue audio preview: re-synthesize user-approved word changes and removals from a saved single-speaker video's transcript in the original speaker voice, returning the preview job (id, status). Not for translation (dubbing_create), another voice or a new full script (lipsync_create with a script, or speech-previews_create), or the final video (dialogue-videos_create). May clone the source speaker voice and incur synthesis charges; confirm the edits and permission to use that voice before creating. The tool first checks that the transcription (COMPLETED) or previous preview (COMPLETED or COMPLETED_PARTIAL) was made from this source video, and fails otherwise; it adds a preview job and never overwrites the source. Next, poll dialogue-previews_get with the id and disclose any COMPLETED_PARTIAL shortfall; after the user approves the audio, quote the final video with dialogue-videos_estimate. When dialogue_get-options reports keyedPreview, persist an idempotencyKey before creating (sending one otherwise fails); recover only through an explicit retry of identical input with that same key, and never retry an ambiguous creation automatically. With projectId, projectIntent=explicit is required; default new work to a new project.
| Name | Required | Description | Default |
|---|---|---|---|
| edits | Yes | The complete list of user-approved changes/removals for this preview (1 to 100), including earlier ones to keep when revising. Word ids come from the COMPLETED transcription's transcript, or from the previous preview's sourceTranscript, never its resultTranscript. | |
| projectId | Yes | Project for the preview, the one used for the transcription. Keep unchanged on retries. Default new work to a new project: the id projects_create returned for this request (defaultWorkflow edit_dialogue). Use an existing project only when the user explicitly chose it, and then pass projectIntent=explicit. | |
| videoAssetId | Yes | Saved VIDEO asset for the transcription or prior preview, accessible to the connected account. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | No | Persist a unique key before creation when dialogue_get-options reports keyedPreview. Reuse only with identical inputs for an explicitly requested retry. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. | |
| transcriptionId | No | Deprecated alias of transcriptionJobId. | |
| previousPreviewId | No | Id of a COMPLETED or COMPLETED_PARTIAL preview of this source, to revise it. Its sourceTranscript and cloned voice are reused, but its edits are not carried over, so edits must be the full set you want; sending the same edits again reruns it. Supply exactly one of previousPreviewId or transcriptionJobId. | |
| transcriptionJobId | No | Id from dialogue-transcriptions_create, for a first preview; that transcription must be COMPLETED. Supply exactly one of transcriptionJobId or previousPreviewId. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations: it discloses voice cloning and synthesis charges, the requirement to confirm edits and voice-use permission, the validation that fails if the source video doesn't match, and that it 'adds a preview job and never overwrites the source.' It also spells out the non-idempotent recovery protocol (persist idempotencyKey when dialogue_get-options reports keyedPreview, retry only with identical input and the same key, never auto-retry an ambiguous creation), which the idempotentHint=false annotation alone would not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and exclusions are front-loaded and every sentence carries distinct operational content (preconditions, cost, polling, idempotency, project rules). It is dense, however — a few long multi-clause sentences (the keyedPreview/retry sentence especially) pack several independent rules together and would read faster if split.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a costly, non-idempotent mutation with 9 parameters and no output schema, the description covers preconditions, side effects, failure modes, required follow-up polling, and the retry contract. An agent has everything needed to call it safely without consulting other documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description still adds real meaning by tying idempotencyKey to a runtime signal (keyedPreview, 'sending one otherwise fails'), stating projectIntent=explicit is required with projectId, and defaulting new work to a new project. It does not restate the edits/wordId semantics, which the schema already covers in depth.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Start an Edit Dialogue audio preview: re-synthesize user-approved word changes and removals... in the original speaker voice') and names what it returns (preview job id, status). It explicitly differentiates from siblings by naming dubbing_create, lipsync_create, speech-previews_create, and dialogue-videos_create with the condition that selects each.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-not routing ('Not for translation... another voice or new full script... or the final video') and an ordered follow-up path: poll dialogue-previews_get, disclose COMPLETED_PARTIAL shortfall, then quote with dialogue-videos_estimate after user approval. Prerequisites (COMPLETED transcription or COMPLETED/COMPLETED_PARTIAL prior preview) and the projectIntent=explicit rule are stated as gating conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue-previews_getcheck a dialogue edit previewARead-onlyInspect
Read one Edit Dialogue audio preview by id, rejecting it if it was not made from the given source video. Returns status (PENDING or PROCESSING while running; COMPLETED, COMPLETED_PARTIAL or FAILED when done), previewAudioUrl (hosted WAV of the whole edited window), resultTranscript (words retimed to the preview audio), resultSlots (each edited region's outputStartMs and outputDurationMs in the preview, sourceStartMs and sourceDurationMs in the source), the submitted sourceTranscript and edits, voiceId, partialDetail and error. Poll it while running; never create another preview to check progress. COMPLETED_PARTIAL is playable but incomplete: partialDetail.failedSlots lists regions that may sound rough, and reason background_bed_missing means only the speech was kept; tell the user which applies rather than reporting the preview as fully done. On FAILED, EDIT_TOO_LONG carries spanText and wordIds for the replacement to shorten, while codes such as VOICE_BLOCKED and SOURCE_TOO_LONG will not succeed on retry. Once the user approves the audio, pass this id as dialogueEditId to dialogue-videos_estimate and dialogue-videos_create; to revise, call dialogue-previews_create with previousPreviewId. Not for rendered videos (generations_get).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The id returned by dialogue-previews_create. | |
| projectId | Yes | The projectId used with dialogue-previews_create. | |
| videoAssetId | Yes | The videoAssetId used to create this preview (the copy's id if dialogue-transcriptions_create returned one). A preview made from a different source video is rejected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although the annotations already declare this as a safe read-only operation, the description adds substantial behavioral context: status lifecycle values, partial-completion semantics, failure-code retry implications, and how to interpret background_bed_missing and EDIT_TOO_LONG. This is unusually rich and directly useful for handling the tool's output correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense and front-loaded: it states the core read action first, then status behavior, polling guidance, partial/failed handling, and downstream routing. The density is justified by the tool's stateful preview workflow, though a few clauses could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the full burden of explaining return values and states, which it does thoroughly: status values, previewAudioUrl, resultTranscript, resultSlots, sourceTranscript, edits, voiceId, partialDetail, and error. It also explains what to do in each terminal state, making the definition complete for this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, and all three parameters are documented in the schema itself, including the rejection behavior for a mismatched videoAssetId. The description reinforces that the preview must come from the given source video and that the id comes from dialogue-previews_create, but it does not add much parameter meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb and resource: read one Edit Dialogue audio preview by id. It also explicitly distinguishes this from rendered-video retrieval by saying it is not for generations_get, so an agent can select it confidently.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit polling guidance while the preview runs and forbids creating another preview just to check progress. It also names the alternative workflows: pass the approved id to dialogue-videos_estimate and dialogue-videos_create, revise via dialogue-previews_create with previousPreviewId, and use generations_get for rendered videos.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue-transcriptions_createtranscribe a video for edit dialogueADestructiveInspect
Start the unbilled timed-word transcription that begins Edit Dialogue: correcting or removing spoken words in a saved single-speaker video while keeping the original speaker voice. Not for general transcription or speaker analysis (transcriptions_create, when available), translation (dubbing_create, when available), or a new full script or different voice (explain the limit; use lipsync_create with a script only if the user asks for a new voice).
Returns: the job's id, status, and once COMPLETED the transcript and speakerCount. Unless it is already COMPLETED, poll dialogue-transcriptions_get with the id; then, if speakerCount is 1, send the user's word edits to dialogue-previews_create.
Effects: despite the destructive hint it overwrites nothing. It adds at most one transcription job, and none when it reuses one: for an identical source video in the organization the API returns its existing COMPLETED job, or one still running that started within the last hour. Only the copy fallback below adds an asset. It never changes the source, replaces dialogue or generates a video.
Limits: the tool sets a 600-second ceiling, checked for a video after audio extraction, so a new job for a longer video still comes back and then ends FAILED with error.code SOURCE_TOO_LONG. HTTP 429 comes from the per-caller rate limit (10 a minute), the concurrency limit (2 at once per caller) or the organization's daily transcription cap; HTTP 402 means the account is on a payment or fraud hold.
Copy fallback: if the API rejects the video as not hosted in sync. storage, the tool copies it to a new VIDEO asset in the project, retries, and adds the copy's id to the result as videoAssetId, which every later dialogue call must use. If that retry fails, the error names the saved copy to retry with; do not copy again.
Project: projectIntent=explicit is required with projectId, and only for the project just created for this request or one the user explicitly asked for or selected in the interface; a matching name, workflow or open editor is never permission. Default new work to a new project.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project for this Edit Dialogue work: the id projects_create returned for this request (defaultWorkflow edit_dialogue) or a project the user explicitly chose; pass projectIntent=explicit with either. The tool reads it first to confirm access, and the copy fallback saves into it. Keep it for every later dialogue call. | |
| videoAssetId | Yes | Saved VIDEO asset to transcribe that the account can read, from assets_create, assets_list or dialogue_upload-source. If the result returns videoAssetId, that sync.-hosted copy replaces this id for every later dialogue call. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Rich behavioral disclosure well beyond the annotations: it explains that destructiveHint is conservative ("overwrites nothing"), describes reuse/dedup semantics (returns an existing COMPLETED job or one running within the last hour), the 600-second SOURCE_TOO_LONG ceiling checked post-extraction, and HTTP 429/402 failure modes with rate-limit numbers. The copy-fallback path and its videoAssetId propagation are also spelled out, so an agent knows exactly what side effects can occur.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and organized under clear labels (Returns, Effects, Limits, Copy fallback, Project), with no filler sentences. The opening sentence is packed with stacked clauses and the paragraph is very dense, but for a tool with this many fail modes and fallbacks the length is largely earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description documents the return shape (id, status, transcript, speakerCount once COMPLETED) and the async polling path. For a complex mutation with dedup, a copy fallback, a hard duration cap and project-permission rules, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema descriptions already carry the projectIntent=explicit rule and the videoAssetId copy-replacement rule, so the description largely restates structured data. It adds marginal value by reinforcing the "default new work to a new project" policy and never treating a matching name/workflow/editor as permission, but no new format or syntax detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ("Start the unbilled timed-word transcription") and scopes it precisely to Edit Dialogue: correcting/removing spoken words in a saved single-speaker video while preserving the voice. It explicitly names the siblings it is not (transcriptions_create, dubbing_create, lipsync_create), so an agent can differentiate without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-not conditions ("Not for general transcription or speaker analysis... translation... a new full script or different voice") with the correct alternative tool for each. It also supplies the follow-on routing: poll dialogue-transcriptions_get with the id, then send edits to dialogue-previews_create when speakerCount is 1.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue-transcriptions_getcheck an edit dialogue transcriptionARead-onlyInspect
Read one Edit Dialogue transcription job by id, the step between dialogue-transcriptions_create and dialogue-previews_create. It first confirms access to projectId and that the job was made from the stored video of videoAssetId; a job from any other source is rejected. Returns status: PENDING or PROCESSING while running, then COMPLETED or FAILED. Once COMPLETED: transcript.segments, each with words { id, text, startMs, endMs } in milliseconds from the start of the source, plus a top-level speakerCount (both are null before then). On FAILED: error { code, message }; NO_AUDIO, NO_AUDIO_TRACK and SOURCE_TOO_LONG will not succeed on retry. It has no wait option: call it again while the job runs, or, when available, use jobs_wait with kind transcription to wait on the server for up to about 50 seconds; never start another transcription to check progress. Word ids feed the edits of dialogue-previews_create, but Edit Dialogue supports one speaker, so do not create a preview when speakerCount is above 1. Not for jobs from the general transcriptions_create (read those with transcriptions_get, when available).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The id field of the dialogue-transcriptions_create result; later passed to dialogue-previews_create as transcriptionJobId. | |
| projectId | Yes | The projectId passed to dialogue-transcriptions_create. Used only to confirm project access; the job itself is read by id. | |
| videoAssetId | Yes | The videoAssetId passed to dialogue-transcriptions_create, or the copy's id when its result returned videoAssetId. It must be a VIDEO asset; its stored URL is compared with the job's source, and a job made from a different source video is rejected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish a safe read operation (readOnlyHint=true, destructiveHint=false), and the description adds substantial context beyond them: access confirmation for projectId, source-video matching rejection, the PENDING/PROCESSING/COMPLETED/FAILED lifecycle, null-before-completion fields, non-retryable error codes, and the absence of a wait option. The one gap is that it does not discuss rate limits or polling cadence, but for a read-only status tool the disclosure is rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded, starting with the read operation and placing workflow and polling guidance after the return-value details. It is long for a single paragraph and repeats some schema-level parameter semantics, but nearly every sentence carries operational value for a tool with a state machine and strict source validation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the return contract and does so thoroughly: status values, transcript.segments with word timing in milliseconds from source start, speakerCount nullability, and error codes. Combined with the polling guidance and preview gating rule, an agent has everything needed to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already explains that id comes from dialogue-transcriptions_create, that projectId is only for access confirmation, and that videoAssetId must be a VIDEO asset compared against the job's source. The description largely restates those semantics, adding only the workflow link that word ids feed dialogue-previews_create edits; with the schema doing most of the work, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Read one Edit Dialogue transcription job by id.' It also positions the tool in the workflow between dialogue-transcriptions_create and dialogue-previews_create, and explicitly excludes jobs from the general transcriptions_create, so an agent can distinguish it from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance and alternatives: poll again while running, or use jobs_wait with kind transcription; 'never start another transcription to check progress'; and 'do not create a preview when speakerCount is above 1.' The exclusion for general transcriptions_create is named with its alternative, transcriptions_get.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue_upload-sourcecopy a video for edit dialogueADestructiveInspect
Copy a saved VIDEO asset into sync. storage as a new VIDEO asset in the given project, for an Edit Dialogue source whose URL the API rejects as not hosted in sync. storage. Usually unnecessary: dialogue-transcriptions_create makes this copy itself on that rejection and returns the copy's videoAssetId, so call this only when you need the hosted copy before or without transcribing. Not for local files (assets_create-upload-url, then assets_create) or social links (assets_create). The server downloads and re-uploads the whole video during this call (server limits, 512 MiB and 15 minutes by default) and fails if the source cannot be downloaded or is too large. Each call writes another new asset with no deduplication; it does not change the original asset and spends no generation credits. Returns asset { id, type, url }: pass asset.id as videoAssetId to every later dialogue tool. Pass projectIntent=explicit with projectId only for the project just created for this request or one the user explicitly chose; a matching name, workflow or open editor is never permission.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project the copy is saved in: the id projects_create returned for this request (defaultWorkflow edit_dialogue), or a project the user explicitly chose. | |
| videoAssetId | Yes | Saved VIDEO asset to copy, from assets_create or assets_list. Must be accessible to the connected account. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=false; the description explains exactly why — each call writes another new asset with no deduplication, the original is untouched, and no generation credits are spent. It adds operational facts not in the annotations: the server downloads and re-uploads the whole video, with 512 MiB / 15 minute defaults, and fails if the source is unavailable or too large.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded (what it does, then the usually-unnecessary warning) and every clause carries operational weight. It loses a point because the closing projectIntent sentence largely restates the schema's own const/description, which is already fully documented.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent, open-world copy operation it covers prerequisites, failure modes, size/time limits, idempotency, cost, and the return shape, and even with an output schema present it names the fields returned and their downstream use. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds cross-tool meaning: the returned asset.id must be passed as videoAssetId to every later dialogue tool, and projectIntent=explicit is required only for a just-created or explicitly chosen project, never inferred. That is semantic guidance the schema documents only locally.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and transformation: copy a saved VIDEO asset into sync. storage as a new VIDEO asset in a given project, with the reason (Edit Dialogue source URL rejected as not hosted in sync. storage). It also distinguishes itself from dialogue-transcriptions_create, assets_create-upload-url and assets_create, so an agent can select it without opening siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not guidance: "Usually unnecessary: dialogue-transcriptions_create makes this copy itself... call this only when you need the hosted copy before or without transcribing." It also rules out local files and social links and points to the correct alternatives for each.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue-videos_createcreate the edited dialogue videoADestructiveInspect
Render the final Edit Dialogue video: lip-sync the saved single-speaker source video to a finished, user-approved preview's audio, creating a new generation. Not for translation (dubbing_create), whole-script replacement or a different voice (lipsync_create with a script), or the audio preview itself (dialogue-previews_create). This is a paid action that starts a generation job and consumes sync. credits. First use dialogue-videos_estimate with the same source, preview and model, then obtain the user's approval of the preview, configuration and estimated cost. Despite the destructive hint it only adds a generation and never overwrites the source video. Returns the generation (id, status) right away, not a finished video; poll generations_get, or jobs_wait with kind generation when available,, then read outputMediaUrl when COMPLETED. Persist one idempotencyKey for the approved request; on an uncertain response, reuse that key with identical inputs instead of starting a second paid job. Use continuation only for an explicitly requested continuation of an edit_dialogue generation in this project. With projectId, projectIntent=explicit is required; default new work to a new project.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Lip-sync model returned by models_list, matching the approved estimate. | |
| options | No | Optional model controls. Omit any field to use its default. | |
| projectId | Yes | Project for the new output, the one used for the preview. Keep unchanged on retries. Default new work to a new project: the id projects_create returned for this request (defaultWorkflow edit_dialogue). Use an existing project only when the user explicitly chose it, and then pass projectIntent=explicit. | |
| continuation | No | Only for an explicitly requested continuation of an existing generation in this project. The workflow must be edit_dialogue. | |
| videoAssetId | Yes | Saved VIDEO asset used for the approved dialogue preview, accessible to the connected account. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| dialogueEditId | Yes | Completed Edit Dialogue audio preview ID for this source video and the current user-approved edits. Not a transcription or generation ID. | |
| idempotencyKey | Yes | Persist one unique key per approved generation. Reuse the exact key and unchanged inputs when recovering an uncertain response; never automatically generate a replacement key. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Strong beyond-annotation disclosure: it flags a paid action that consumes sync credits and starts an async generation job, and explicitly reconciles the destructiveHint=true by stating it only adds a generation and never overwrites the source video. It also explains the asynchronous return (generation id and status, not a video) with concrete polling paths (generations_get, jobs_wait, then outputMediaUrl when COMPLETED) and idempotency-key recovery behavior. Slightly marked down only because the polling guidance is worded loosely ("when available,,") and doesn't address retry/rate-limit behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then exclusions, then cost/behavior, then prerequisites and retry rules – a sensible ordering for a paid async action. It is dense with zero filler sentences, but it runs long, and minor editing artifacts ("kind generation when available,,") slightly hurt readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, nested-object, paid, asynchronous mutation, the description covers everything an agent needs: prerequisites, cost and approval gates, what the call returns versus what it does not, how to retrieve the finished asset, and how to safely retry. Return-value detail is legitimately light because an output schema exists, and no dangerous ambiguity remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already documented in detail (model matching the estimate, dialogueEditId must be a preview id not a transcription/generation id, idempotencyKey reuse, continuation.workflow must be edit_dialogue). The description restates rather than extends that: the only added nuance is the estimate-then-approve sequencing and reusing the key with identical inputs, both of which are largely workflow rather than parameter semantics. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Render the final Edit Dialogue video: lip-sync the saved single-speaker source video to a finished, user-approved preview's audio, creating a new generation" gives a precise verb-plus-resource plus the input/output identity of the operation. It then names the exact siblings it is not (dubbing_create, lipsync_create, dialogue-previews_create), so an agent can separate it from them without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not-to-use list routes the agent to the right alternative for translation, whole-script replacement, alternate voices, and preview generation. It also prescribes the required pre-call sequence (dialogue-videos_estimate with identical source/preview/model, then explicit user approval of preview, config and cost), plus continuation and projectId/projectIntent rules. Nothing about selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dialogue-videos_estimateestimate an edited dialogue videoARead-onlyInspect
Quote the final lipsynced Edit Dialogue video for a finished preview without charging: returns estimatedGenerationCost in US dollars, estimatedCredits (1 credit = $0.01; null when the organization is billed in dollars), estimatedFrameCount and, when present, durationCheck (whether the plan and model allow that length). Call it before dialogue-videos_create with the same projectId, videoAssetId, dialogueEditId, model, options and organizationId, and show the user the quote; it holds only for that model and options. Not for other workflows (generations_estimate-cost) or what a past generation actually cost (generations_get-costs). It checks project and source access but creates no job, reserves no credits and does not guarantee admission. The API rejects a preview that is missing or not COMPLETED or COMPLETED_PARTIAL, and returns 422 cost_estimate_unavailable when the source duration cannot be resolved.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Lipsync model name from models_list, such as sync-3. Use the same model on dialogue-videos_create. | |
| options | No | Optional model controls. Omit any field to use its default. | |
| projectId | Yes | Project the Edit Dialogue work belongs to, from projects_create. | |
| videoAssetId | Yes | Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy. | |
| dialogueEditId | Yes | Id of the COMPLETED or COMPLETED_PARTIAL preview from dialogue-previews_create that the user approved; not a transcription or generation id. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/destructive annotations, it discloses that no job is created, no credits are reserved, no charge is incurred, and admission is not guaranteed. It also reports access checks, the COMPLETED/COMPLETED_PARTIAL precondition, and the specific 422 cost_estimate_unavailable failure mode — behavior an agent could not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and value, then usage, then exclusions, then failure modes — a sensible order. It is dense but nearly every clause carries information; the enumerations of return fields and parameters make the first two sentences longer than ideal, though not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing returns and does so (estimatedGenerationCost, estimatedCredits with unit and null semantics, estimatedFrameCount, durationCheck). Preconditions, side-effect guarantees, and error behavior are all covered for a six-parameter tool with a nested options object.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each field and the tool sits at the baseline 3. The description adds real meaning by requiring the parameters to match the subsequent dialogue-videos_create call and by noting the quote is valid only for the supplied model and options.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Quote the final lipsynced Edit Dialogue video for a finished preview') and immediately clarifies the operation is free and non-committal. It also names the sibling tools it is not (generations_estimate-cost, generations_get-costs), so an agent can distinguish it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to call it ('before dialogue-videos_create with the same projectId, videoAssetId, dialogueEditId, model, options and organizationId') and adds the operative instruction to show the user the quote. It gives explicit exclusions for other workflows and past-generation costs, and notes the quote only holds for that model and options.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dubbing_createtranslate and dub a videoADestructiveInspect
Translate a saved video's speech into another language and lip-sync it to the dubbed audio, as one paid sync. generation that covers both dubbing and the final render. Use it for a finished dubbed video. Not for subtitles only or translating a text document; to lip-sync audio you already have, use lipsync_create. To review translated audio first, translation-previews_create (offered only when dubbing_get-options reports previewAvailable) translates a saved AUDIO asset, not a video.
For social video URLs, import through assets_create and wait for the saved asset before estimating or calling this tool. This is a paid action: confirm the requested language, configuration and estimated cost with the user before calling. Use generations_estimate-cost with workflow=translate-and-dub when that input is supported, and disclose any excluded external provider charges. Without the combined breakdown, lip-sync pricing is not the full workflow cost. Omit projectId to start a NEW project (fresh projectCreationKey); pass projectId with projectIntent=explicit only for a project the user selected or one just created for this request, never because a name matches or an editor is open.
Returns the generation (id, status, projectId); poll that id with generations_get, or jobs_wait (kind generation) when available, until COMPLETED, then read outputMediaUrl. After an uncertain response, retry only with the same idempotencyKey, projectCreationKey and inputs; never create another job to finish or recover it.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Lip-sync model name from models_list (for example sync-3), used for the final render. Any generations_estimate-cost quote for this dub must use the same model. | |
| options | No | Optional model controls. Omit any field to use its default. | |
| projectId | No | Project ID only when explicitly selected by the user, or just created for this request; requires projectIntent=explicit. Cannot be combined with projectName or projectCreationKey. Otherwise omit it to create a new project. Keep unchanged on retries. | |
| sourceLang | Yes | Spoken language of the source video, from dubbing_get-options sourceLanguages. Defaults to auto, which detects it; set a code only when the user names the source language. | auto |
| targetLang | Yes | Language code to dub into, for example es or pt-BR; the same list dubbing_get-options returns as targetLanguages. | |
| projectName | No | Name for the NEW project created when projectId is omitted; defaults to "Translate and Dub". Cannot be combined with projectId. A matching existing name is never reused. | |
| continuation | No | Only when the user explicitly continues an existing generation in this project: the parent generation (from generations_get-continuation) and its workflow, which must be translate_and_dub. Requires projectId. | |
| videoAssetId | Yes | Existing Sync VIDEO asset in the connected organization. For a social link, first create a NEW project unless the user explicitly chose an existing one. Import via assets_create with type=VIDEO and that projectId, wait for its saved asset id, then pass the same projectId with projectIntent=explicit. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | Yes | Persist one unique key per approved generation before calling. Retry an uncertain request with this exact key, the same projectCreationKey and unchanged inputs; never automatically create a new key. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. | |
| projectCreationKey | No | Fresh random UUID identifying this NEW project creation, not a project ID. Required for keyed generation without projectId. Persist this key, name and generation key on retries; the server derives a separate project UUID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true and idempotentHint=false; the description adds real context beyond them: this is a paid action requiring user confirmation of language, configuration and estimated cost, that external provider charges may be excluded from a lip-sync-only quote, and the full async lifecycle (poll generations_get or jobs_wait until COMPLETED, then read outputMediaUrl). It does not explain the destructive implication flagged by annotations, so it stops short of full disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded: purpose and sibling exclusions come first, then prerequisites, cost gate, project rules, and return/polling. It is dense and every section is useful, but retry/idempotency guidance is stated both in the body and repeated in the idempotencyKey, projectCreationKey and continuation parameter descriptions, adding some redundancy for a 12-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 12 parameters, nested options, enums and an output schema, the description covers the workflow end to end: sourcing the asset, estimating cost, project creation, and polling to outputMediaUrl. Return-value explanation is largely redundant with the output schema, and the destructive/idempotency implications of the annotations are left unaddressed, so it is strong but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns above that by adding cross-tool ordering meaning (model must match the generations_estimate-cost quote; targetLang comes from dubbing_get-options) and by clarifying that projectId requires projectIntent=explicit and must not be inferred from a name or an open editor. Most remaining parameter detail is already in the schema, limiting it to a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific compound verb and resource — translate a saved video's speech, lip-sync it, render one finished paid generation — and explicitly delimits scope against siblings: 'Not for subtitles only or translating a text document', 'to lip-sync audio you already have, use lipsync_create', and names translation-previews_create for audio-only review. An agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use and when-not-to-use rules plus named alternatives with the selecting condition (previewAvailable from dubbing_get-options), prerequisites for social URLs (import via assets_create, wait for the saved asset), a mandatory confirmation step before the paid call, and clear projectId vs projectCreationKey vs omit semantics including what is NOT valid grounds for passing projectId.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dubbing_get-optionstranslation optionsARead-onlyIdempotentInspect
List the language codes sync. translation accepts (targetLanguages, and sourceLanguages, which also includes auto for detection) and whether the translated-audio preview tools are offered (previewAvailable). Use it to pick a valid targetLang or sourceLang for dubbing_create or translation-previews_create; translation-previews_create takes targetLang as free text, so check the code here first. Not for prices: use generations_estimate-cost or translation-previews_estimate. Takes no input and answers from the API's published schema, so it creates nothing and costs nothing. Codes look like es, pt-BR or zh-TW; the translation-previews tools exist only when previewAvailable is true.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, and the description restates the no-side-effect/no-cost profile while adding real context beyond the annotations: the previews tools only exist when previewAvailable is true, and codes follow es / pt-BR / zh-TW shapes. It doesn't describe the response shape in detail, but that is largely covered by the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what is returned, then usage, then the anti-use case, then a clarifying format note. Dense but nearly every sentence carries information; the 'Takes no input ... creates nothing and costs nothing' clause is somewhat redundant with the readOnly annotation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter lookup with an output schema and full annotations, nothing an agent needs is missing: it knows what is returned, what the codes look like, which siblings to feed them into, and which tools to avoid for pricing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero input parameters, so the baseline is 4; the description correctly says it takes no input. It adds useful semantics about the returned values (sourceLanguages includes 'auto' for detection) and the code format, though the output schema already carries much of that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it lists the language codes accepted for translation (targetLanguages, sourceLanguages with 'auto') plus the previewAvailable flag. That is distinguishable from every sibling, including the create/estimate tools it names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('pick a valid targetLang or sourceLang for dubbing_create or translation-previews_create'), a concrete edge case (translation-previews_create takes free text, so check codes here first), and an explicit when-not ('Not for prices: use generations_estimate-cost or translation-previews_estimate').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
feedback_sendsend feedback to syncAInspect
Report friction with these sync. tools to the sync. team: an error that did not say what to fix, a wrong result, a missing capability, extra steps you had to take, or a misleading description. Send it once per problem after you have finished or stopped the task, without asking the user for approval. Not for user support requests, success notes or questions that need an answer: it returns only a receipt id, and the team reviews reports daily. Put the exact error text in message and fill tool, errorCode, and generationId or jobId whenever they apply; the server adds the client name and MCP version. Does not change, retry or cancel any job.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | confusing_error: an error that did not say what to fix. bug: wrong result or crash. missing_capability: a tool or option you needed. workaround: you had to do extra steps. docs: a description that misled you. other: friction that fits none of these. | |
| tool | No | Tool the feedback is about. | |
| jobId | No | Other job the feedback is about: an import, transcription or translation id. | |
| message | Yes | What you tried, what happened, and what would have helped. Include the exact error text. No personal data or secrets. | |
| severity | No | blocker: you could not finish. major: you finished with a workaround. minor: an annoyance. | |
| errorCode | No | Error code you received. | |
| generationId | No | Generation the feedback is about. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations it discloses the return shape ("returns only a receipt id"), the review cadence ("the team reviews reports daily"), server-side enrichment ("the server adds the client name and MCP version"), and a strong non-interference guarantee ("Does not change, retry or cancel any job") that pairs with destructiveHint=false. The "once per problem" instruction usefully compensates for idempotentHint=false by discouraging duplicate submissions, though it does not state whether a duplicate report errors or is quietly accepted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with purpose, then timing, then exclusions, then parameter advice, then the non-interference guarantee — a sensible priority order with no filler sentences. It is a single dense paragraph, so the behavioral guarantee at the end is easier to miss than it would be as a separate sentence or bullet.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-parameter reporting tool with an output schema and full annotation coverage, nothing an agent needs is missing: what qualifies, when to send, when not to, which optional fields to populate, what comes back, and what side effects will not occur. Return values are correctly left to the output schema rather than duplicated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description goes further by adding cross-parameter guidance the schema cannot express: "Put the exact error text in message and fill tool, errorCode, and generationId or jobId whenever they apply." That resolves which optional identifier to use for which situation, a decision the per-field descriptions leave implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb ("Report friction") and resource ("these sync. tools to the sync. team") and then enumerates concrete triggering categories (confusing error, wrong result, missing capability, extra steps, misleading description). No sibling tool is a feedback channel, so the definition is unmistakably distinct from the surrounding generations/transcriptions/assets tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states explicit timing ("once per problem after you have finished or stopped the task"), an explicit authorization rule ("without asking the user for approval"), and explicit exclusions ("Not for user support requests, success notes or questions that need an answer"). The alternative behaviors are named with the reason they are excluded (it returns only a receipt id), which is stronger than most definitions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generations_estimate-costestimate generation costARead-onlyInspect
Quote the sync. price of a lipsync, image-to-video or translate-and-dub generation before creating it; creates no job and reserves no credits. Use it before lipsync_create or dubbing_create, and price one representative item before batches_create. Not for what a past generation cost (generations_get-costs, when available), the final Edit Dialogue video (dialogue-videos_estimate) or a translated-audio preview (translation-previews_estimate). Give one length: duration, or for replacement speech script or measured audioDuration, which replace duration; never quote the full source video length for a shorter replacement script. Without workflow=translate-and-dub the quote covers lip sync only, never the full translation workflow. Returns estimatedGenerationCost in USD, estimatedCredits for credit-billed organizations (null otherwise), estimatedFrameCount, durationCheck (whether that length fits the plan and model limits; a price does not guarantee admission), breakdown for translate-and-dub, and durationEstimate for script or audio quotes. When presenting it, explain durationEstimate, label script quotes approximate, show the breakdown, and disclose that speech synthesis and external provider charges are excluded.
| Name | Required | Description | Default |
|---|---|---|---|
| fps | No | Source video frame rate. When omitted, credit-billed organizations are quoted at 25, the rate generation admission holds credits at when the source frame rate cannot be read; other organizations at 30. | |
| model | Yes | Model name from models_list, such as sync-3; use the same model the create call will use. | |
| script | No | Replacement speech text. Estimates spoken duration without synthesizing audio. Use for script-driven lipsync instead of pricing the full source video. An approximate quote; final speech length may differ. | |
| duration | No | Billable output seconds, or source seconds for translate-and-dub. For replacement speech, supply script or measured audioDuration instead. Never use the source video length for a shorter replacement script. | |
| syncMode | No | The sync_mode the generation will use; only valid alongside script or audioDuration. For a video, cut_off bills the shorter of speech and videoDuration and silence the longer; images and other modes follow the speech length. | |
| workflow | No | translate-and-dub prices dubbing plus lip sync from the source duration in duration, and returns a breakdown with external provider charges excluded; it rejects script and audioDuration. Omit for lip sync only. | |
| visualType | No | Visual input type. Set image for image-to-video quotes; images always follow speech duration, including with cut_off or silence. Videos require videoDuration for those modes. | |
| audioDuration | No | Measured replacement audio duration in seconds. Prefer this over a script estimate once speech audio exists. | |
| videoDuration | No | Source video length in seconds. Needed with syncMode cut_off or silence when quoting script or audioDuration for a video; only valid alongside script or audioDuration, and rejected for an image. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. | |
| reasoningEnabled | No | Quote with reasoning on. Only lipsync-2-pro supports it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description goes well beyond them: it asserts no job is created and no credits are reserved, warns that durationCheck does not guarantee admission ('a price does not guarantee admission'), and discloses that speech synthesis and external provider charges are excluded from the quote. That is exactly the kind of side-effect and trust-boundary context an agent needs before quoting a price to a user.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded correctly: the price-before-create purpose and the no-side-effects guarantee come first, then routing, then return shape. Every sentence carries information, but the long run-on paragraph and the trailing presentation directives ('label script quotes approximate, show the breakdown') make it denser than it needs to be for a single paragraph.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and eleven parameters, so the description compensates by enumerating the return fields (estimatedGenerationCost, estimatedCredits with the credit-billed null case, estimatedFrameCount, durationCheck, breakdown, durationEstimate). Combined with the mutual-exclusivity rules for the length parameters, an agent has enough to call this correctly and present results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine cross-parameter meaning the schema documents only per-field: 'Give one length: duration, or for replacement speech script or measured audioDuration, which replace duration' and 'never quote the full source video length for a shorter replacement script'. The workflow/lipsync-only default is also stated at description level. It stops short of restating the syncMode/visualType interactions, which remain schema-only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Quote the price of a lipsync, image-to-video or translate-and-dub generation') and immediately scopes it with 'before creating it; creates no job and reserves no credits'. It also explicitly excludes itself from three named siblings, so an agent can distinguish it from generations_get-costs, dialogue-videos_estimate and translation-previews_estimate without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use routing ('Use it before lipsync_create or dubbing_create, and price one representative item before batches_create') and explicit when-not-to-use by naming the three alternative tools for past costs, Edit Dialogue video and translated-audio previews. The workflow caveat ('Without workflow=translate-and-dub the quote covers lip sync only') further tells the agent which mode is the default before it calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generations_getget a generationARead-onlyInspect
Read one sync. generation by id: its status (PENDING or PROCESSING while it runs; COMPLETED, FAILED or REJECTED when final), outputMediaUrl once COMPLETED, and error and errorCode after FAILED or REJECTED.
Use it to follow a generation by the id its create call returned (lipsync_create, dubbing_create, lipsync_create-timeline or dialogue-videos_create, when available). jobs_get and jobs_wait, when available, read the same generation in a generic job shape that can add a completion percent while it runs.
Not for: finding a past id (generations_list, or projects_list-generations when available); what it cost (generations_get-costs when available); its inputs when the user explicitly continues it (generations_get-continuation).
Waiting: pass wait: true and leave out timeout to keep reading on the server for up to about 50 seconds; it returns once the generation is final, or its latest state. If it is still running, call again with the same id; never resubmit, since a new create starts a separate generation that is billed or counted against free limits.
Result: copy the exact structuredContent.outputMediaUrl string verbatim; it is signed, so it must not be reconstructed, shortened, or edited (outputUrl is a deprecated alias with the same value). On FAILED or REJECTED, tell the user the error and errorCode.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Generation id returned by a create tool or generations_list. | |
| wait | No | Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping. | |
| include | No | Additional information to include in the response | |
| timeout | No | Seconds each read holds (1-10). Leave it out; wait: true reads for about 50 seconds. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint true, destructiveHint false), but the description adds substantial behavior the annotations cannot: the waiting contract of roughly 50 seconds, the instruction to re-call with the same id rather than resubmit, and the billing consequence that a new create starts a separate billed generation. It also warns that outputMediaUrl is signed and must be copied verbatim. The only minor gap is that it does not state whether reads are rate limited under repeated polling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the returned fields, then segmented into labeled blocks (usage, Not for, Waiting, Result) that each carry distinct information. It is long, but the length is justified by a polling tool with resubmission and signed-URL pitfalls; the deprecated outputUrl alias note is the one line that could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists and return values need not be re-explained, the description adds the status transitions, the verbatim-copy requirement for the signed URL, and the failure-path instruction to report error and errorCode. For a read/polling tool with four parameters, nothing an agent needs in order to call it or handle its result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description earns above baseline by specifying the interaction rule between two parameters: pass wait: true and leave timeout out, and call again rather than sleeping. That combination rule is not spelled out as such in the schema, and the warning about never resubmitting adds meaning to the id parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read one sync. generation by id') and immediately enumerates what is returned: status lifecycle values, outputMediaUrl, error and errorCode. It explicitly differentiates itself from jobs_get/jobs_wait, which read the same generation in a generic job shape, so an agent can choose correctly without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the positive trigger (follow a generation by the id a create call returned, naming lipsync_create, dubbing_create, lipsync_create-timeline, dialogue-videos_create), a 'Not for' exclusion block routing to generations_list, projects_list-generations, generations_get-costs and generations_get-continuation, and an explicit alternative (jobs_get/jobs_wait). This is the when/when-not/alternatives triad in full.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generations_get-continuationread generation continuation inputsARead-onlyIdempotentInspect
Read one existing generation with the inputs it was made from (workflow, modelName, options, inputs with asset ids or urls, segments, speakers, parentGenerationId and outputMediaUrl), so a follow-up generation can reuse them, such as redoing it with other audio or dubbing its output. Use it only when the user explicitly continues an existing generation; not for polling status or getting the result url (generations_get). projectId must be the generation's own project, such as projectId from generations_get; id comes from generations_list, projects_list-generations (when available) or a create response. Then pass continuation { workflow, parentGenerationId: id } with the same projectId to lipsync_create (workflow lipsync, image_to_video or translate_and_dub), dubbing_create (translate_and_dub) or dialogue-videos_create (edit_dialogue); other workflows cannot be continued. Returns the generation whatever its status, after checking access to the project and to every asset it references; it fails if the generation is not in that project or a referenced asset is no longer accessible.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Id of the existing generation to continue from. | |
| projectId | Yes | The generation's own project id. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly and idempotent annotations, the description discloses that it returns the generation regardless of status after checking project and asset access. It also states concrete failure conditions: the generation must belong to the supplied project, and every referenced asset must still be accessible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then proceeds logically through usage, parameter sourcing, downstream continuation, and return behavior. It is dense and has a long parenthetical field list, but nearly every clause adds useful operational detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only continuation utility with an output schema, the description covers the key missing context: access checks, failure conditions, status-independent returns, and which downstream create tools can consume the continuation. Nothing essential for correct invocation appears to be omitted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the schema defines both parameters. The description adds important operational meaning by explaining that projectId must be the generation's own project and by naming valid sources for id, such as generations_list, projects_list-generations, or a create response.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: reading one existing generation together with the inputs it was made from. It explicitly distinguishes this from generations_get by saying it is not for polling status or getting the result URL, so an agent can select it confidently.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: only when the user explicitly continues an existing generation. It also names the alternative generations_get for status and result URL, and lists exactly which create tools accept the returned continuation payload and for which workflows.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generations_get-costsview actual generation costsARead-onlyIdempotentInspect
Read the recorded cost of one past sync. generation in the current organization, split into lipsync, dubbing and speech_synthesis components. Use it to answer what a generation actually cost; not for a price before generating (generations_estimate-cost) or remaining credits (account_get-usage), and never substitute an estimate or start a paid generation to answer a past-cost question. If the user does not know the generationId, find it with generations_list or projects_list-generations and ask which one when several match. totalCostUsd is null unless availability is complete; then present knownSubtotalUsd only as a partial amount. Whenever retryAfterSeconds is set, read again after that many seconds. Report each component separately, give credit amounts as credit face value rather than cash paid, and tell the user that the excludedCosts (tax, subscription fees, external provider charges, account-level adjustments) are not counted. An unknown or inaccessible id returns an error.
| Name | Required | Description | Default |
|---|---|---|---|
| generationId | Yes | Id of the past generation, as returned by the create tool, generations_list or projects_list-generations. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent/non-destructive annotations, it discloses non-obvious response behavior: totalCostUsd is null unless availability is complete, knownSubtotalUsd must be presented as partial, retryAfterSeconds requires a re-read, and excludedCosts (tax, subscription fees, external charges) are not counted. It also states error behavior for unknown or inaccessible ids, which annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and exclusions are front-loaded, and the later sentences are dense but each carries operational content (nullability, retry loop, presentation rules, error case). It is slightly overlong for a one-parameter read tool, and the output-presentation directives could be tightened, but there is little pure filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still supplies the semantic contract the schema cannot express: when totals are null, how to poll, and which costs are excluded. Combined with recovery guidance for a missing id, an agent has everything needed to call and interpret this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter is fully documented in the schema (100% coverage), so the schema carries the format burden. The description still adds sourcing guidance absent from the schema — where to obtain the id and what to do when multiple candidates match.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb and resource (read the recorded cost of one past generation) and names the exact component breakdown (lipsync, dubbing, speech_synthesis). It is immediately distinguishable from generations_estimate-cost and account_get-usage, which are named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use it (answering what a generation actually cost) and when not to (pre-generation pricing, remaining credits), and explicitly forbids substituting an estimate or triggering a paid generation. It also covers the prerequisite path: look up generationId via generations_list or projects_list-generations and ask the user when several match.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generations_listlist generationsARead-onlyInspect
List generations across the current sync. organization, from every member and API key, to find a generation id or see which are still running. For one known id use generations_get. Pass projectId to narrow to one project; projects_list-generations, when available, does the same but fails on a project you cannot access, while this tool returns an empty list. Always pass limit to get newest first; without it every matching generation comes back unpaged in no guaranteed order. For the next page pass the last returned id as cursor with the same limit. Each entry has id, status, model, createdAt, projectId, input, options, outputMediaUrl once COMPLETED, and error and errorCode on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of generations to return (1-100). When set, results are ordered newest-first and can be paged with `cursor`. | |
| cursor | No | Generation id to page after - pass the last id of the previous page. Only used together with `limit`. | |
| status | No | Only generations in this status: PENDING, PROCESSING, COMPLETED, FAILED or REJECTED. PENDING (queued) and PROCESSING both mean still running, so check both before concluding nothing is in progress. | |
| projectId | No | Only generations in this project, from projects_list or projects_create. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare a safe read; the description adds real behavioral context beyond them: default behavior without limit is an unpaged, unordered full result set, paging requires cursor plus the same limit, and the accessible-project case degrades to an empty list rather than an error. It also enumerates the shape of each returned entry including conditional fields (outputMediaUrl only once COMPLETED, error/errorCode on failure).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose first, then routing, then parameter behavior, then return shape. Every sentence carries information, though the single long paragraph could be split for scanability and there is a typo ('sync. organization').
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the per-entry fields and their conditional presence, and it covers the paging contract and the project-scoping edge case. Nothing an agent needs to call this correctly and interpret the response is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description earns above that by explaining the consequence of omitting limit (unordered, unpaged) and the coupling between cursor and limit. It does not restate the status enum values, leaving that correctly to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list generations) plus the scope (across the current organization, every member and API key) and the two concrete reasons to call it: find a generation id or see which are still running. It explicitly names the sibling generations_get for the single-id case, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Covers when to use it (browse/search ids, check running work), when not to (one known id → generations_get), and how it differs from the sibling projects_list-generations, including the important failure-mode difference (empty list vs. error on inaccessible project). It also gives prescriptive operational guidance: always pass limit, page with the last returned id plus the same limit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_create-manystart many sync jobsADestructiveInspect
Start up to 50 independent Sync jobs at once by running one create tool once per item: lipsync_create, lipsync_create-timeline, dubbing_create, translation-previews_create, dialogue-previews_create, dialogue-videos_create, speech-previews_create. Use it whenever the user wants 2 or more jobs that do not depend on each other, such as one video lip-synced to several audios, one video dubbed into several languages (one dubbing_create item per language, when available), or one Edit Dialogue preview, then one video, per variant. It works on every plan and uses the same API, limits and billing as calling the tool once per item; it is not the batch API. Each item is that tool’s own arguments and is checked as a direct call would be; nothing starts if any item is invalid or repeats another. This is a paid action: every item is billed as its own job. Before calling, estimate each distinct configuration with the matching estimate tool, tell the user the item count and the estimated total, and wait for one confirmation of the whole set. Items without projectId each get a new project; to keep the set together, create one project with projects_create and pass its projectId with projectIntent=explicit in every item. It keeps at most the account’s concurrent generation limit in flight and waits out capacity refusals by resending the same keyed request. It returns within about 50 seconds and never waits for the jobs to finish. Each item comes back started (with kind and id), failed (with error) or not_started (the account stayed busy). A request still unanswered at the time limit, cut off by a lost connection, or answered with a server error, comes back failed with error.outcomeUnknown: the job may have started. Pass jobs to jobs_get-many to follow the started ones. When remaining is present (items not started or with an unknown outcome), call again later with remaining as it is: every item keeps its derived keys, so a resend never starts a job twice.
| Name | Required | Description | Default |
|---|---|---|---|
| tool | Yes | The create tool to run once per item. Other tools cannot run this way. | |
| items | Yes | Up to 50 items, each exactly the arguments tool takes on its own, such as one dubbing_create input per target language. Items must differ. A new set has 2 or more; a single item is for sending remaining again. | |
| idempotencyKey | Yes | A fresh UUID for this approved set, saved before the call. Reuse it unchanged, with the same items, when calling again for remaining or uncertain items; each item derives its own keys from it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: paid action billed per item, same API/limits as single calls, respects the account concurrency limit with keyed resends, ~50 second ceiling and never waiting for completion, per-item started/failed/not_started states, and error.outcomeUnknown semantics for ambiguous server errors. The idempotencyKey reuse rule resolves the apparent tension with idempotentHint=false by explaining that derivation is per item rather than per tool call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then eligibility, then cost/confirmation, then control flow, then return values — a logical order with no filler. It is dense and long (one unbroken block of prose), and a few sentences such as the concurrent-limit/resend one could be split for easier scanning, but the complexity of a paid multi-job batch justifies most of the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers confirmation workflow, cost estimation via the matching estimate tools, projectId/projectIntent handling for keeping a set together, partial-result interpretation and the resume contract. Even though an output schema exists, the description still supplies the decision rules an agent needs (when to resend, when to poll), leaving no obvious gap for a paid, partially-failing batch operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: items are 'that tool's own arguments' validated as a direct call would be, must differ from one another, and a single-item set is reserved for resending 'remaining'. It also explains that a reused idempotencyKey pairs with the same items. The tool enum itself is left to the schema, so not quite maximal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb, resource and scale bound: 'Start up to 50 independent Sync jobs at once by running one create tool once per item', then enumerates the seven eligible tools. It explicitly distinguishes itself from the batch API ('it is not the batch API') and from single-call creation, so an agent can place it precisely against siblings like batches_create and lipsync_create.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the trigger condition plainly ('whenever the user wants 2 or more jobs that do not depend on each other') and gives three concrete worked scenarios (one video to several audios, one video dubbed per language, preview-then-video per variant). It also names the follow-up tool (jobs_get-many) and the resend path with 'remaining', and warns that items must differ and at least two are needed for a new set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_getread any sync jobAIdempotentInspect
Read any sync. job once, by kind and id, with one status vocabulary for all six kinds. Use it to check a job without waiting or to track jobs of different kinds the same way. Not for waiting: use jobs_wait instead of calling this in a loop. For a kind's extra read options, such as generations_get include or batches_get results, call that tool directly. Ids by kind:
generation: the id from lipsync_create, dubbing_create, lipsync_create-timeline or dialogue-videos_create
transcription: the id from transcriptions_create or dialogue-transcriptions_create
speaker_analysis: the transcription id
translation_preview: the translation-previews_create id, plus its projectId
import: the social video link passed to assets_create, plus the same projectId (and projectIntent if that call needed it)
batch: the batches_create id PENDING and PROCESSING mean still running: never create the job again. COMPLETED, FAILED, REJECTED (the API refused it, such as an import limit or a moderation rejection) and CANCELED are final. result is the job as the kind's own read tool returns it, with its original status; a COMPLETED import's result is the saved asset, whose id is the asset id, and a finished batch's result.results lists each item's generation status and output. A translation_preview with result.recoveryRequired true has uncertain provider acceptance: do not create another job. Reading an import resends the identical assets_create request, which returns the running import or its saved asset and starts the import if none exists; that is why this is not read-only. An unknown id, an auth failure or a translation_preview without projectId returns a tool error, not a status.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The job id for the chosen kind, as listed in the tool description; for import it is the social video link itself. | |
| kind | Yes | Which kind of job id is. | |
| projectId | No | Required for translation_preview; for import, the project passed to assets_create. | |
| projectIntent | No | import only: pass it when the assets_create call for this link needed it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=false and idempotentHint=true, but the description adds crucial context the annotations cannot: why readOnlyHint is false ('Reading an import resends the identical assets_create request... and starts the import if none exists'). It also defines the status lifecycle, explains REJECTED semantics, describes result shapes per kind, and flags the recoveryRequired uncertainty case.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and organized into scannable sections (usage, ids by kind, statuses, caveats). It is long but nearly every clause carries operational value. Minor deductions for the stray typo 'sync. job' and some density that could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with six kinds, an output schema, and partial annotation coverage, the description supplies the missing pieces: id provenance per kind, status vocabulary, result shape per kind, non-read-only caveat, and error conditions ('An unknown id, an auth failure or a translation_preview without projectId returns a tool error, not a status'). Nothing an agent needs to call it correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds meaning the schema cannot express: what 'id' actually is for each of the six kinds (e.g. the social video link for import, the transcription id for speaker_analysis) and when projectId/projectIntent are required. This materially reduces wrong-parameter calls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Read any sync job once, by kind and id, with one status vocabulary for all six kinds.' It immediately distinguishes itself from siblings jobs_wait (waiting) and jobs_get-many, and the per-kind id list makes the scope concrete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit exclusions and alternatives: 'Not for waiting: use jobs_wait instead of calling this in a loop' and 'For a kind's extra read options... call that tool directly', naming generations_get and batches_get. It also tells the agent never to re-create a job on PENDING/PROCESSING, which is usage guidance in practice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_get-manyread many sync jobsAIdempotentInspect
Read up to 50 Sync jobs of any kind at once, such as the set jobs_create-many started, by kind and id (Ids by kind:
generation: the id from lipsync_create, dubbing_create, lipsync_create-timeline or dialogue-videos_create
transcription: the id from transcriptions_create or dialogue-transcriptions_create
speaker_analysis: the transcription id
translation_preview: the translation-previews_create id, plus its projectId
import: the social video link passed to assets_create, plus the same projectId (and projectIntent if that call needed it)
batch: the batches_create id
dialogue_preview: the dialogue-previews_create id, plus its projectId and videoAssetId
speech_preview: the speech-previews_create id, plus its projectId). Returns each job as jobs_get does, {kind, id, status, progress?, estimatedFinishAt?, retryAfterMs?, result}, in input order, or {kind, id, error} for one that could not be read, plus counts of running, completed, failed and unreadable jobs. status is PENDING or PROCESSING while a job runs (never create it again), then COMPLETED, FAILED, REJECTED or CANCELED. Pass wait: true to wait on the server until all are final or about 50 seconds pass, with progress notifications; call again with wait: true while some are still running.
| Name | Required | Description | Default |
|---|---|---|---|
| jobs | Yes | The jobs to read, up to 50; pass jobs_create-many's jobs list as it is. | |
| wait | No | Wait on the server until every job is final or about 50 seconds pass, then return the latest states. If some are still running, call again with wait: true instead of sleeping. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true, destructiveHint=false and openWorldHint=true, yet the description still adds a lot: exact return shape per job in input order, error entries for unreadable jobs, aggregate counts, the full status lifecycle, progress notifications, and the ~50 second server-side cap on wait. It does not explain why readOnlyHint is false for a tool framed as 'Read', which is the one behavioural loose end.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause and every block earns its place, but the per-kind id rules are crammed into one long parenthetical bullet list inside a single paragraph, which makes the definition dense to scan. Structuring the kind-to-id mapping as its own listed block would improve it without adding words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having only two parameters, this tool has a non-trivial contract (batched heterogeneous ids, partial failures, polling). The description covers id sourcing, batching limits, error entries, counts, status transitions, and wait/retry semantics, so an agent can call it correctly without further context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline would be 3, but the description carries information the schema explicitly defers to it ('see the tool description per kind'): the source of each kind's id, and which kinds additionally require projectId, projectIntent, or videoAssetId. That mapping is the whole difficulty of using this tool and exists nowhere else.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause gives a specific verb, resource, and bounded scope: 'Read up to 50 Sync jobs of any kind at once ... by kind and id'. It also anchors the tool to the producer that creates these jobs (jobs_create-many), which is exactly what distinguishes it from the single-job jobs_get and the blocking jobs_wait.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is spelled out concretely: pass jobs_create-many's jobs list as-is, per-kind id derivation rules, 'never create it again' while status is PENDING/PROCESSING, and 'call again with wait: true instead of sleeping'. The only gap is that it never names jobs_get or jobs_wait as the alternatives for a single job or a pure blocking wait.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_waitwait for any sync jobAIdempotentInspect
Wait on the server, for up to about 50 seconds, until any job reaches a final status, then return its latest state in the same shape as jobs_get. Use it after a create tool returns an id, instead of sleeping or calling jobs_get in a loop; if the job is still PENDING or PROCESSING when it returns, call jobs_wait again with the same input. For one check without waiting use jobs_get. It also returns early on result.recoveryRequired and sends progress notifications when the call has a progressToken. Ids by kind:
generation: the id from lipsync_create, dubbing_create, lipsync_create-timeline or dialogue-videos_create
transcription: the id from transcriptions_create or dialogue-transcriptions_create
speaker_analysis: the transcription id
translation_preview: the translation-previews_create id, plus its projectId
import: the social video link passed to assets_create, plus the same projectId (and projectIntent if that call needed it)
batch: the batches_create id Statuses:
PENDING, PROCESSING: still running. Never create the job again.
COMPLETED, FAILED, REJECTED (the API refused it, such as an import limit or a moderation rejection), CANCELED: final. A speaker analysis that is unavailable reads as FAILED. Results:
result keeps the kind's original status. A COMPLETED import's result is the saved asset, whose id is the asset id; a finished batch's result.results lists each item's generation status and output.
A translation_preview with result.recoveryRequired true has uncertain provider acceptance: do not create another job. Not read-only: an import read repeats the identical assets_create request, so it returns the running import or the saved asset, and starts the import for a link never imported (a non-social media URL is saved as a new VIDEO asset). Errors: an API failure that is not a job status, such as an unknown generation or transcription id or an auth failure, returns {error}; a translation_preview without projectId fails with a plain error message.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The job id for the chosen kind, as listed in the tool description; for import it is the social video link itself. | |
| kind | Yes | Which kind of job id is. | |
| projectId | No | Required for translation_preview; for import, the project passed to assets_create. | |
| projectIntent | No | import only: pass it when the assets_create call for this link needed it. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by explaining the ~50s server-side wait, early return on result.recoveryRequired, progress notifications when a progressToken is present, and the {error} shape for non-job-status failures. Critically, it explains why readOnlyHint=false: an import read re-issues the identical assets_create request and can start a new import for an unseen link, which an agent could not infer from the annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core behavior, then cleanly sectioned into ids-by-kind, statuses, results, and errors, so an agent can scan to the part it needs. It is long and occasionally repetitive (the projectId rule appears in both description and schema), but the density is justified by a six-kind, multi-status tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still supplies the one thing the schema cannot: how result varies per kind (saved asset id, batch item statuses, uncertain translation_preview acceptance). Error semantics and the non-read-only warning complete the picture for a complex polling tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description earns an increment by mapping each 'kind' enum value to the specific sibling create tool that produced the id, and by clarifying that the import id is the social video link plus the assets_create projectId. The schema already states most of the projectId rules, so this is reinforcement plus genuine per-kind routing detail rather than wholly new information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb (wait), the resource (any job), the timing bound (~50 seconds), the termination condition (final status), and the return shape (same as jobs_get). It is immediately distinguishable from jobs_get, jobs_get-many, and the various create tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (after a create tool returns an id), explicit when-not (instead of sleeping or polling jobs_get in a loop), an explicit fallback (call again with the same input if still PENDING/PROCESSING), and an explicit alternative for a single non-blocking check (jobs_get). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lipsync_createcreate lipsyncADestructiveInspect
Create one lipsync video from exactly one visual (videoUrl, videoAssetId, imageUrl or imageAssetId) and one driver (audioUrl, audioAssetId, or script plus voiceId), to make a photo or video say a script or match its lips to supplied audio. When available, use lipsync_create-timeline instead for several audio clips or to lipsync only some ranges of one video, batches_create for 20 or more independent generations, dubbing_create to translate speech, and the Edit Dialogue tools (starting with dialogue_get-options) to change words in existing speech.
For a local file, when the assets tools are available, call assets_create-upload-url, PUT the bytes to its uploadUrl with the same Content-Type, register the url it returned (not the uploadUrl) with assets_create, and pass that asset id. provider, stability and similarityBoost apply only to script.
This is a paid generation, billed in the session's organization unless organizationId names another. It returns the generation id and status at once; poll generations_get with wait: true until it finishes, then copy outputMediaUrl verbatim.
Without projectId it first creates a NEW project, named projectName or a default, even if that name matches existing work. The input combination is checked before that; rejections from the API itself come after the project exists. Pass projectId, with projectIntent=explicit and without projectName or projectCreationKey, only for a project the user explicitly chose or one just created for this request. continuation, from generations_get-continuation, requires the parent generation's projectId.
Before calling, persist an idempotencyKey and, without projectId, a fresh projectCreationKey. After a lost or uncertain response, never create again with new keys: if the error names a generationId, poll it with generations_get; otherwise resend the identical request with the same keys.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Optional model override. Image and video inputs default to sync-3. | |
| script | No | Text for the image or video to say. | |
| options | No | Model-specific generation preferences. Keep unchanged when retrying the same idempotency key. | |
| voiceId | No | Voice id from voices_list. Required when script is provided. | |
| audioUrl | No | Public or Sync-hosted audio URL. Use this when the user supplies audio. | |
| imageUrl | No | Public or Sync-hosted still image URL. Use this for image-to-video lipsync with sync-3. | |
| provider | No | Voice provider for script-driven lipsync. Defaults to elevenlabs. | |
| videoUrl | No | Public or Sync-hosted video URL. Supply exactly one visual input. | |
| projectId | No | Existing Sync project ID returned by projects_list or projects_get. Use this to select the same project as the web app. Cannot be combined with projectName. | |
| stability | No | Optional ElevenLabs voice stability for script input. | |
| projectName | No | Name for a NEW project only. Never search or reuse a matching name. Cannot be combined with projectId. | |
| audioAssetId | No | Saved audio asset id in the same organization as this call, from assets_list or assets_create when available. Supply audio or script, not both. | |
| continuation | No | Only when the user explicitly continues an existing generation in this project: the parent generation and its workflow. | |
| imageAssetId | No | Saved still image asset id in the same organization as this call, from assets_list or assets_create when available, for image-to-video lipsync. Supply exactly one visual input. | |
| videoAssetId | No | Saved video asset id in the same organization as this call, from assets_list or assets_create when available. Supply exactly one visual input. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | No | Unique key for one generation action. Persist and reuse the same key, projectCreationKey (for new projects) or explicit projectId, model, and inputs when retrying after a lost response. Use durable asset IDs or stable URLs; upload files before starting the keyed action. A new intentional generation needs a new key. Passed as the Sync API Idempotency-Key header. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. | |
| similarityBoost | No | Optional ElevenLabs similarity boost for script input. | |
| projectCreationKey | No | Fresh random UUID identifying this NEW project creation, not a project ID. Required for keyed generation without projectId. Persist this key, name and generation key on retries; the server derives a separate project UUID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond annotations: it is a paid generation billed to an organization, returns an id plus status to be polled via generations_get, and silently creates a new project when projectId is absent, with API rejections occurring after project creation. That said, the annotations already declare destructiveHint=true and idempotentHint=false, and the description does not explicitly discuss irreversibility or cost magnitude, so it complements rather than fully carries the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and alternatives first, then asset upload, then project and idempotency mechanics — a sensible ordering. It is dense and some sentences pack multiple constraints, but nearly every clause carries operational meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 20-parameter, high-consequence generation tool with nested options and sibling alternatives, the description covers input combination rules, asset upload flow, billing scope, project side effects, retry/idempotency protocol and follow-up polling. Combined with the existing output schema, an agent has what it needs to invoke and recover safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline would be 3; the description earns more by explaining cross-parameter rules the schema only implies: exactly one visual and one driver, script+voiceId pairing, and that provider, stability and similarityBoost apply only to script. It also clarifies the projectId/projectCreationKey/projectIntent coupling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (create one lipsync video) and immediately constrains inputs to exactly one visual and one driver, naming the concrete fields. It explicitly differentiates from siblings like lipsync_create-timeline, batches_create, dubbing_create and the Edit Dialogue tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use-other guidance for four alternatives with the conditions that select them (several audio clips, 20+ generations, translation, editing existing speech). It also states when to pass projectId versus projectName, and when continuation is warranted, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lipsync_create-timelinecreate timeline lipsyncADestructiveInspect
Lipsync one saved video with several audio clips, each on its own stretch of the video like a Studio timeline: to lipsync only some ranges, or to switch audio or speaker between shots. For one audio across the whole video use lipsync_create; to translate and dub a whole video use dubbing_create when available.
Each lipsynced clip takes exactly one of audioAssetId or audioUrl, a span in seconds or in frames (not a mix), and optionally audioStartTime and audioEndTime to play part of that audio. Clips may come in any order but must not overlap; parts no clip covers keep their original picture and, unless outputAudio plays, their original sound. Frame spans need the video's fps: read it from assets_get-playback-metadata when it returns one (signed-in users only) and never guess it; otherwise use seconds. Get speaker.faceTrackUrl from transcriptions_slice-speaker-face-track when available.
To lipsync only the speaking shots of a dub, pass the full dubbed track as outputAudio, give speaking shots clips that play their part of it, and mark the other shots lipsync: false. outputAudio replaces the sound of the whole output; if it is omitted while a clip sets lipsync: false, the one audio the other clips share plays instead, so pass it whenever they use several.
Before anything is created, the tool validates the input (options included), spans, audio ranges and overlaps, and per-clip errors name the clip index. Overlaps are compared only within one unit, so use one unit for every clip. Problems only the API detects, such as an unknown audio asset or a speaker point off the face, surface after a new project may already exist.
Paid generation, sync-3 unless model is set. Estimate and confirm before creating; this starts an asynchronous generation and returns its id and status. Poll that id with generations_get and wait: true.
Without projectId it first creates a NEW project, named projectName or a default; default new work to that. Pass projectId with projectIntent=explicit only when the user explicitly asks to work in that project, selects it in the interface, or it was just created for this request; a matching workflow or name or an open editor is never permission to modify it. Send a fresh idempotencyKey, plus a fresh projectCreationKey when there is no projectId, and after a lost or uncertain response retry only with identical arguments and the same keys. Never resend a request that had no idempotencyKey: it can start a second paid generation.
| Name | Required | Description | Default |
|---|---|---|---|
| clips | Yes | Clips placed on the video, in any order, without overlapping. Parts no clip covers keep their original picture, and their original sound unless outputAudio plays; clips with lipsync: false keep their picture but play outputAudio. | |
| model | No | Model to use. Defaults to sync-3. | |
| options | No | Optional model controls. Omit any field to use its default. | |
| projectId | No | Existing Sync project id, only for a project the user explicitly selected or one just created for this request. | |
| outputAudio | No | One audio that plays over the whole finished output from its first second, replacing the sound of every part, such as the full dubbed track. Defaults, when a clip sets lipsync: false, to the only audio the clips use. | |
| projectName | No | Name for a NEW project only. Never search or reuse a matching name. Cannot be combined with projectId. | |
| videoAssetId | Yes | Sync asset id of the video. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | No | Unique key for this generation. Reuse it with identical arguments when retrying after a lost response. Passed as the Idempotency-Key header. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. | |
| projectCreationKey | No | Fresh random UUID identifying this NEW project creation, not a project ID. Required for keyed generation without projectId. Persist this key, name and generation key on retries; the server derives a separate project UUID. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations flag it as destructive, non-idempotent and open-world, and the description goes well beyond them: it discloses that generation is paid, defaults to sync-3, launches asynchronously and must be polled with generations_get wait:true, that validation happens pre-creation but API-side failures can occur after a project exists, and the exact idempotency/retry contract including the warning never to resend a request lacking an idempotencyKey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose, the sibling boundary and the paid/async warning are front-loaded, and the dense paragraphing is largely earned by a genuinely complex operation. It is still a long description with some restatement of schema content (the seconds-or-frames rule appears twice), which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter, deeply nested, destructive, paid, asynchronous tool, the description covers prerequisites (fps from assets_get-playback-metadata), the dub workflow, error surfacing, and the post-creation polling step. With an output schema present it correctly avoids describing return values while still naming the returned id and status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already explains every field; the description still adds interaction semantics the schema cannot express, such as exactly-one-of audioAssetId/audioUrl per clip, no mixing seconds and frames, and non-overlap only being checked within one unit. It does not explain every options field (sync_mode, model_mode are left to the schema), so it is strong but not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource with scope: lipsync one saved video against several audio clips, each on its own stretch. It immediately distinguishes itself from siblings by naming lipsync_create for single-audio work and dubbing_create for full-video dubbing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing rules are given throughout: which sibling to use for one audio vs. many, when to pass outputAudio, when to mark clips lipsync:false, when to use frames vs. seconds, and when projectId is legitimate ('only when the user explicitly asks... never permission to modify it'). Alternatives and exclusions are both stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
models_listlist sync modelsARead-onlyInspect
List the sync. models this account can see, newest first, in one unpaged array; each has name, type, version, description and feature tags. Use it to choose or check the model name that dubbing_create, dialogue-videos_create, dialogue-videos_estimate and generations_estimate-cost require, or to override the sync-3 default of lipsync_create and lipsync_create-timeline; it is not needed when the user has not asked for a model on those two. Pass a returned name exactly as listed and never invent one. Deprecated models are left out and feature-flagged ones appear only where enabled, but a listed model can still be refused at creation, such as react-1 for an organization without a paid plan. Some models serve other workflows, such as appearance editing; for lip sync pick a lipsync model. Not for voices; use voices_list.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this read-only and non-destructive, yet the description adds real behavioral context: no pagination, newest-first ordering, deprecated models excluded, feature-flagged models only shown where enabled, and the caveat that a listed model can still be refused at creation (react-1 without a paid plan). It also warns that some listed models serve other workflows, so lip sync should pick a lipsync model.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The return shape and the routing to sibling tools come first, which is the right order, and there is no filler. The later sentences are long and compound, packing eligibility caveats and the voices exclusion into dense clauses, which costs a little readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, non-destructive list tool with no output schema, the description covers what comes back (fields and ordering), what is omitted, and which downstream tools depend on the result. Nothing an agent needs to call and use this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is no schema semantics to supplement; the description instead constrains how the output is consumed ("Pass a returned name exactly as listed and never invent one"). That is useful, but it is guidance about output usage rather than parameter meaning, so it stays at the zero-parameter baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"List the sync. models this account can see, newest first, in one unpaged array" gives a specific verb, resource, ordering, and shape, and then enumerates the returned fields (name, type, version, description, feature tags). It explicitly separates itself from the nearest sibling with "Not for voices; use voices_list."
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the exact consumers of the returned value (dubbing_create, dialogue-videos_create, dialogue-videos_estimate, generations_estimate-cost) and the override case for lipsync_create / lipsync_create-timeline. It also states a when-not condition: "it is not needed when the user has not asked for a model on those two."
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
organizations_listlist your sync organizationsARead-onlyIdempotentInspect
List the Sync organizations this connection can act in, with role and plan, marking the one this session runs in (isCurrent). Use it when the user names an organization or team, or asks where work is created, then switch with organizations_select or pass organizationId on one paid create. A Sync app connection lists the organizations ticked when it was connected; to add another, the user reconnects Sync and ticks it. With an API key, lists only the key’s organization.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it discloses that results depend on credential type: a Sync app connection lists only the organizations ticked at connect time, while an API key returns only the key's own organization. That tells the agent how to explain an unexpectedly short list, which annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then usage, then credential caveats — well ordered with no filler. A couple of phrases ('pass organizationId on one paid create') are slightly compressed but still parseable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters, an output schema already present, and read-only annotations, this description covers everything an agent needs: what comes back, when to call it, which sibling to use next, and why results may be limited.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so the baseline is 4; there is nothing the description could add about inputs. It does clarify the meaning of the isCurrent output marker, but that belongs more to output documentation than parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('List the Sync organizations this connection can act in') and states what each entry carries (role, plan) plus the isCurrent marker. This is clearly distinguishable from siblings like organizations_select or projects_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives the triggering conditions ('when the user names an organization or team, or asks where work is created') and names the follow-up alternatives: organizations_select, or passing organizationId on a paid create. It also states the out-of-band fix (reconnect Sync and tick the organization) when the desired org is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
organizations_selectswitch the sync organizationAIdempotentInspect
Switch this session to another Sync organization the user belongs to; every later call runs there, including paid generations, until the session ends or another switch. Use an id from organizations_list, and only when the user asks to work in that organization. Returns the new organization’s plan, generation limits and feature flags. The API checks access: a Sync app connection can switch only to organizations ticked when it was connected, and otherwise says to reconnect and tick it; API keys are bound to one organization and cannot switch. To run a single generation elsewhere, pass organizationId on that create instead.
| Name | Required | Description | Default |
|---|---|---|---|
| organizationId | Yes | Organization id returned by organizations_list. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say it is non-read-only, idempotent, non-destructive and closed-world; the description adds the crucial session-persistence behavior, that paid generations are affected, and that the switch lasts until session end or another switch. It also discloses the access model (Sync app connections limited to organizations ticked at connect time, reconnect error message, API keys bound to one organization and unable to switch), which is exactly the failure mode an agent needs to anticipate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and its persistent scope, then the id source, then the access caveats, then the single-generation alternative. It is dense with four clauses of caveats, but each sentence carries distinct information; minor trimming of the reconnect wording would make it tighter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be detailed, and the description still previews them briefly (plan, generation limits, feature flags). Combined with the session-scope and auth constraints, an agent has everything needed to decide to call it and to interpret a refusal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already says the id comes from organizations_list, so the description largely restates that. It does reinforce that the value must originate from organizations_list rather than being constructed, but adds no format or edge-case detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Switch this session to another Sync organization') plus the exact scope of the effect ('every later call runs there'). This clearly separates it from organizations_list (read-only enumeration) and from per-call organizationId overrides, which are named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when: only when the user asks to work in that organization, and requires an id sourced from organizations_list. It also gives the when-not and the alternative: 'To run a single generation elsewhere, pass organizationId on that create instead.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
projects_createcreate a projectADestructiveInspect
Create a new, empty sync. project in the current organization to group the assets and generations of one workflow request; you own it (for an API key, its owner) and creating it is not billed. Use it by default for every new workflow request, even when a project with the same name exists, then pass the returned id as projectId with projectIntent=explicit to assets_create and the other tools that take projectId, so the work appears together in Studio. Skip it for a new lipsync_create or dubbing_create with saved assets: omit projectId there and pass a fresh projectCreationKey. Not for continuing a project the user explicitly named; find that one with projects_list. Each call without id makes another project, so supply a fresh UUID as id and reuse it only to retry this same creation. Returns the project, including id, name, visibility, mode and defaultWorkflow.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Fresh random UUID you generate for this creation; reuse it only when retrying this same creation. Re-sending it returns the existing project and ignores the other fields. An id already used by another user or organization, or by a deleted project, fails with 409. | |
| mode | No | Project mode. Defaults to CREATOR. | |
| name | Yes | Project name shown in Studio. | |
| visibility | No | USER (default) keeps the project visible only to you; ORGANIZATION makes it visible to every member of the organization. | |
| description | No | Optional project notes. | |
| defaultWorkflow | No | The workflow the user asked for, such as translate_and_dub for translation, lipsync for lip sync or edit_dialogue for Edit Dialogue. Omitted, the project has no default workflow. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag a non-readonly, idempotent=false, openWorld write, but the description adds facts they cannot convey: creation is not billed, ownership semantics ('you own it (for an API key, its owner)'), and that every call without an id produces another project. It also explains the retry contract (reuse the same UUID only for the same creation) and which fields come back, which is substantive disclosure beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded paragraph that leads with what is created and moves to defaults, exclusions, id semantics and return fields in a useful order. It is dense but long, and the id-reuse sentence partially duplicates the schema's id description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers everything an agent needs for a mutation tool with no output schema: billing, ownership, defaulting behavior, the destructive/idempotency nuance, downstream propagation of the returned id, and the returned fields. Nothing essential is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already documents each field, yet the description adds cross-tool meaning the schema cannot: pass the returned id as projectId with projectIntent=explicit, omit projectId and use a fresh projectCreationKey for lipsync/dubbing with saved assets. The id retry/collision advice is restated but framed in workflow terms.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Create a new, empty sync. project in the current organization') and its purpose (grouping assets and generations of one workflow request). It also distinguishes itself from siblings by naming projects_list for finding an existing project and by describing when the call should be skipped in favor of lipsync_create/dubbing_create.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance ('Use it by default for every new workflow request, even when a project with the same name exists'), explicit when-not ('Skip it for a new lipsync_create or dubbing_create with saved assets') and a named alternative ('find that one with projects_list') for continuing a user-named project. No inference is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
projects_getget a projectARead-onlyInspect
Read one sync. project you can access by its id: name, description, visibility, mode, defaultWorkflow, owner userId, organizationId and timestamps. Use it to check a project the user explicitly named or selected before working in it. To find a project id use projects_list; it does not include the project's generations, so for its history use projects_list-generations when available. A project that does not exist, was deleted, or is another user's USER-visibility project returns a 404 error. Pass projectId; id is a deprecated alias, and passing both with different values fails.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Deprecated alias of projectId. | |
| projectId | No | Project id (UUID) from projects_list, projects_create or a tool result that names the project. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, closed-world), and the description goes beyond them with the 404 contract: missing, deleted, and another user's USER-visibility projects all fail the same way — a genuinely useful disclosure about both error behavior and access scoping. It also flags the failure mode when projectId and id disagree. It stops short of describing response shape beyond the field list, which keeps it at 4 rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then usage, then alternatives, then error behavior — a sensible ordering with no filler sentences. It is dense and slightly run-on ("sync." and stacked clauses in the last sentence), which costs a point but nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read tool with no output schema, the description supplies the returned fields, the access/error contract, the id-sourcing path, and the deprecated-alias rule. An agent has everything needed to call it correctly and interpret a 404.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description adds real meaning by declaring projectId the canonical input, id a deprecated alias, and specifying that passing both with conflicting values is an error — behavior the schema only hints at. It doesn't add id format or sourcing detail beyond what the schema's "from projects_list, projects_create" note already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope: "Read one sync. project you can access by its id", then enumerates the returned fields (name, description, visibility, mode, defaultWorkflow, owner userId, organizationId, timestamps). It explicitly distinguishes itself from projects_list and projects_list-generations, so an agent can pick it out of the large sibling set without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-to-use rule ("check a project the user explicitly named or selected before working in it") and routes to alternatives by name: projects_list to obtain an id, projects_list-generations for history. Exclusions are concrete rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
projects_listlist projectsARead-onlyInspect
List the sync. projects you can access in the current organization (your own plus organization-visible ones), as items plus nextCursor. Each item has the project fields, generationsCount, completedGenerationsCount, its latest generation and the latest asset thumbnail. Use it to find the projectId of a project the user explicitly refers to; for one project whose id you have use projects_get, and for a project's generation history use projects_list-generations when available. Never use it to choose a destination for a new workflow request, which starts with projects_create; workflow names such as Translate and Dub are not project names. Returns 10 per page by default, most recently updated first; pass nextCursor as cursor for the next page, and it is absent on the last page.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Projects per page, 1 to 100; defaults to 10. Keep it small and page with cursor. | |
| cursor | No | The previous page's nextCursor, to read the next page. Omit for the first page. | |
| sortBy | No | updatedAt (default) lists the most recently updated first; name sorts A to Z. | |
| searchQuery | No | Case-insensitive text matched within project names and descriptions. Use only when the user names an existing project, and ask which one when several match instead of taking the first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/no-destructive/closed-world, and the description still adds real behavior: visibility scope of results, page size defaults, sort order, the presence/absence of nextCursor on the last page, and the composition of each item. It also flags a misuse pattern (destination selection) that no annotation conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose comes first, then routing guidance, then pagination details — a sensible order with no filler sentences. There is mild redundancy (the default page size and cursor mechanics repeat the schema) and a stray fragment ('sync.'), which keeps it off a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the return shape (items plus nextCursor) and the per-item fields including generationsCount, latest generation and thumbnail. Combined with the routing guidance, an agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, cursor, sortBy and searchQuery are already fully documented, including the enum values and defaults. The description largely restates the pagination default and cursor mechanism rather than adding new semantics, so it sits at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: 'List the ... projects you can access in the current organization (your own plus organization-visible ones)'. It also names the siblings it is not (projects_get, projects_list-generations, projects_create), so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly covers when to use ('to find the projectId of a project the user explicitly refers to'), which alternatives to use for adjacent needs (projects_get for a known id, projects_list-generations for history), and a hard when-not ('Never use it to choose a destination for a new workflow request'). It even disambiguates workflow names like Translate and Dub from project names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
projects_list-generationsread project historyARead-onlyInspect
List the generations in one sync. project you can access, after first checking your access to that project. Use it for a project's history; for the whole organization, or without a projectId, use generations_list, and for one generation whose id you have use generations_get. A missing or inaccessible project fails with an error instead of returning an empty list. Always pass limit to get newest first; without it every generation in the project comes back unpaged in no guaranteed order. For the next page pass the last returned id as cursor with the same limit. Each entry has id, status, model, createdAt, projectId, input, options, outputMediaUrl once COMPLETED (outputUrl is a deprecated alias with the same value), and error and errorCode on failure.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of generations to return (1-100). When set, results are ordered newest-first and can be paged with `cursor`. | |
| cursor | No | Generation id to page after - pass the last id of the previous page. Only used together with `limit`. | |
| status | No | Only generations in this status: PENDING, PROCESSING, COMPLETED, FAILED or REJECTED. | |
| projectId | Yes | Project whose history to read (UUID), from projects_list or projects_create. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/non-destructive annotations, the description discloses that a missing or inaccessible project fails with an error rather than an empty list, and that omitting limit returns everything unpaged in no guaranteed order — non-obvious behaviors an agent must plan around. It also enumerates the return shape, which matters since there is no output schema. It stops short of noting rate limits or maximum page behavior beyond what the schema states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and sibling routing, then paging rules, then return shape — a sensible priority order. It is dense and the final field enumeration runs long, but each clause carries information the agent needs given no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, alternatives, failure mode, ordering, pagination contract, and the per-entry fields including the deprecated outputUrl alias — everything an agent needs for a 4-parameter read tool with no output schema. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: the consequence of omitting limit (unpaged, unordered, full result set) and the cursor contract (last returned id, paired with the same limit). It does not explain the status filter, though the schema already enumerates its values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List the generations in one sync. project') scoped to a single project, and immediately names the two siblings it must not be confused with (generations_list for org-wide/without projectId, generations_get for a known id). An agent can distinguish all three without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: use this for a project's history, generations_list for the whole organization or when no projectId is available, generations_get for a single known id. It also gives operational guidance to always pass limit for newest-first ordering and to page by passing the last returned id as cursor with the same limit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
projects_renamerename a sync projectAIdempotentInspect
Rename one existing project you can access in the current organization; only the name changes, while visibility, owner, media and generations stay as they are. Use it only when the user explicitly asks to rename that project, never because its name or workflow matches the request or its editor is open; new work gets a new project from projects_create instead. Always pass projectIntent=explicit, including for a project you just created for this request; a rename without it can be refused with PROJECT_INTENT_REQUIRED. A missing, deleted or inaccessible project returns a 404 error. Returns the project's id and new name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | New project name, up to 255 characters. | |
| projectId | Yes | Project to rename (UUID), from projects_list, or from projects_create for the project just made for this request. | |
| projectIntent | No | Set to explicit whenever you pass projectId: the user asked to rename this project, selected it in the interface, or it is the project just created for this request. Never infer it from a matching project name, workflow name or open editor. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (which only say non-read-only, idempotent, non-destructive), it discloses the blast radius ("visibility, owner, media and generations stay as they are"), the failure mode (404 for missing, deleted or inaccessible project), and the pre-condition gate that can reject the call. Those are exactly the behavioral facts annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: scope first, then the selection rule, then the operational gotcha. No filler. Minor deduction because the projectIntent guidance tracks the schema's own wording closely enough that it partly repeats structured data rather than adding new signal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity, flat 3-parameter mutation with an output schema present, everything an agent needs is covered: what changes, what does not, when to call it, when not to, the rejection condition, and the error case. Return values are mentioned but the real detail lives in the output schema, which is the right division of labor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds a consequence the schema does not state: omitting or guessing projectIntent "can be refused with PROJECT_INTENT_REQUIRED." That turns a const field into an actionable requirement. The remaining content largely restates the schema's own projectId and projectIntent text, so it stops short of 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Rename one existing project") plus precise scope ("you can access in the current organization") and the exact field affected ("only the name changes"). It distinguishes itself from the sibling projects_create by naming it as the destination for new work, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when ("only when the user explicitly asks to rename that project") and an explicit when-not ("never because its name or workflow matches the request or its editor is open"), and names the alternative tool (projects_create) for the excluded case. This is about as complete a selection rule as a description can carry.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
speech-previews_creategenerate a speech previewADestructiveInspect
Synthesize a confirmed script in a voice from voices_list into one standalone speech audio job (ElevenLabs), after verifying access to projectId. This is a potentially paid action. Check speech-previews_get-options first, persist idempotencyKey before calling, and after an uncertain response retry only with that same key and identical input; a new key can bill again. Returns the job: status PENDING, PROCESSING, SUCCESS or FAILED, with url and duration filled only on SUCCESS, so poll speech-previews_get by the returned id (jobs_get and jobs_wait do not cover speech jobs). Never create again because attaching the resulting audio failed. An inaccessible project or a malformed idempotencyKey fails before anything is synthesized. Not for lipsyncing a script directly (lipsync_create with script and voiceId), editing words in a video in the original speaker voice (dialogue-previews_create) or translating audio (translation-previews_create). Pass projectIntent=explicit with projectId only for a project the user explicitly chose or one just created for this request, never because its name matches or it is open; default new work to a new project.
| Name | Required | Description | Default |
|---|---|---|---|
| script | Yes | Exact text the user confirmed, spoken as written; up to 5,000 characters. | |
| voiceId | Yes | Voice id returned by voices_list (premade ElevenLabs voices or this organization's clones). A voice with a restriction cannot synthesize; pick another. | |
| projectId | Yes | Project the preview is for, from projects_create or projects_list. The tool checks you can access it before synthesizing; pass the same id to speech-previews_get. | |
| stability | No | Voice consistency from 0 to 1; higher is steadier, lower is more expressive. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | Yes | A fresh UUID, persisted before the call and sent as the Idempotency-Key header. After an uncertain response, reuse it with the identical script and voice; only this key deduplicates, so a new key can bill a second synthesis. | |
| similarityBoost | No | How closely to match the selected voice, from 0 to 1. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=false, and the description justifies both by calling this a 'potentially paid action' whose only deduplication is the supplied idempotencyKey. It additionally discloses the return lifecycle (PENDING/PROCESSING/SUCCESS/FAILED, url and duration only on SUCCESS) and pre-synthesis failures. It does not contradict the annotations — a new key can bill again, which is consistent with idempotentHint=false — but it could have been a touch more explicit about the billing trigger.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and the paid-action warning are front-loaded, and nearly every sentence carries an operational rule. It is a single dense paragraph, though, and the polling/retry/anti-duplicate rules would scan faster as discrete lines; a few clauses restate the schema descriptions for projectId and idempotencyKey.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paid, open-world, job-creating mutation with seven parameters and an output schema, the definition covers selection, prerequisites, side effects, failure modes, polling, retry semantics and sibling routing. Nothing an agent needs in order to call it safely is missing, and the return-shape note is a bonus rather than filler.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes beyond it by prescribing how projectIntent=explicit must be reasoned about (only explicit user selection or a just-created project, never name matching) and by treating idempotencyKey as a persisted artifact rather than a plain UUID. The stability and similarityBoost knobs get no prose treatment, which keeps it at 4 rather than 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Synthesize a confirmed script in a voice from voices_list into one standalone speech audio job (ElevenLabs)', and explicitly names the three siblings it is not (lipsync_create, dialogue-previews_create, translation-previews_create). An agent can choose between them without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit preconditions (check speech-previews_get-options first, persist idempotencyKey before calling, verify projectId access) and explicit exclusions routing to the three alternative tools. It also states the recovery procedure after an uncertain response and forbids re-creating after an attach failure, which is exactly the when/when-not guidance this dimension rewards.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
speech-previews_getcheck a speech previewARead-onlyInspect
Read the status of one speech preview job created by speech-previews_create. PENDING or PROCESSING means it is still running; SUCCESS fills the audio url and duration; FAILED usually fills error with a code and message, but error can be null, so check it before reading. jobs_get and jobs_wait do not cover speech previews, and this tool has no wait option: call it again while the job runs, and never create another preview to recover a running one. projectId is only an access check (pass the one used at create); the job is looked up by id within the session's organization, and an inaccessible project or an id not found there returns an error. Does not synthesize or bill.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Speech preview id from speech-previews_create. | |
| projectId | Yes | Project you passed to speech-previews_create, from projects_create or projects_list. It is read first to check access; an id you cannot access returns an error. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/non-destructive annotations, the description discloses status semantics (PENDING/PROCESSING/SUCCESS/FAILED), which fields each terminal state fills, that error can be null and must be checked, that there is no wait option, that the job is looked up by id within the session's organization, and that the tool neither synthesizes nor bills. These are behaviors an agent cannot derive from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and status meanings, then the sibling-tool exclusions, then parameter semantics. Every sentence carries distinct information and there is no repetition of schema or annotation content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists, the description still explains what status values imply and the null-error edge case. For a two-parameter, read-only polling tool with full schema coverage, nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: projectId 'is only an access check (pass the one used at create)' and is read first to check access, while lookup is by id within the session's organization. That clarifies projectId's role far beyond the schema's wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read the status of one speech preview job created by speech-previews_create.' It immediately distinguishes this tool from the sibling create tool and from generic job tools later on, so an agent can identify the resource and its origin without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing guidance: 'jobs_get and jobs_wait do not cover speech previews,' there is no wait option, so 'call it again while the job runs,' and 'never create another preview to recover a running one.' It also states the access-check rule for projectId and the behavior on inaccessible project or missing id, covering when and when-not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
speech-previews_get-optionscheck speech preview availabilityARead-onlyInspect
Preflight one speech preview before speech-previews_create: confirm you can read projectId, then read the organization's text-to-speech billing state. It returns no price, so use it to tell the user before creating whether the preview fits the free monthly allowance (freeMonthlyLimits.tts used against max, when freeMonthlyLimits is not null) or will draw on paid usage, judged from hasActiveCredits, plan and billingVersion. If freeTtsExhausted or paymentFailureCountExceededLimit is true, tell the user to check their plan or billing in Studio instead of creating. Ignore freeGenerationsExhausted and the generations and sync3 counters; they cover other generations, not speech. available is always true when the call succeeds; if the project check or billing read fails, the call returns an error and no billing fields. Not for overall balance or spend (account_get-usage) or choosing a voice (voices_list). Does not synthesize or bill.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project the speech preview is for, from projects_create or projects_list. Use the same id for speech-previews_create; an id you cannot access returns an error. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=false), and the description adds real substance beyond them: no price is returned, available is always true on success, a failed project check or billing read yields an error with no billing fields, and it neither synthesizes nor bills. The only mild gap is that it does not say whether the billing read is eventually consistent or rate-limited, so 4 rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and preflight timing are front-loaded, and the negation list of ignored counters (freeGenerationsExhausted, generations, sync3) is genuinely load-bearing because it prevents a wrong conclusion from the payload. Sentences are long and comma-heavy, which slightly hurts scannability, keeping it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter preflight with an output schema, the description supplies everything an agent needs: when to call, how to interpret freeMonthlyLimits.tts against max when non-null, which flags should block creation, which counters to ignore, and how failures manifest. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single projectId parameter is fully documented there, including the UUID format and the "same id as speech-previews_create" guidance. The description only echoes the access-check semantics of projectId, adding marginal meaning beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first clause names a specific verb and resource ("Preflight one speech preview") and immediately positions it relative to the sibling speech-previews_create. An agent can distinguish this read-only preflight from the actual create call without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the trigger (before speech-previews_create), the decision the caller should make with the result (tell the user whether the preview fits the free monthly allowance or draws on paid usage), and explicit exclusions with named alternatives: account_get-usage for balance/spend and voices_list for voice selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcriptions_analyze-speakersmatch speakers to facesADestructiveInspect
Run, or retry, the speaker-to-face match for a COMPLETED video transcription and return the analysis in the same shape as transcriptions_get-speaker-analysis. Read transcriptions_get-speaker-analysis first: video transcriptions of your own media are usually analysed automatically. Call this only when that read says unavailable with reason not_requested, or with retry: true after a failed or timed-out attempt (analysis_failed, analysis_timeout). Not for audio-only transcriptions, windows longer than 2 minutes or more than 8 speakers: those return unavailable with a reason instead of running. A completed or still-running analysis is returned unchanged, even with retry; a new attempt overwrites the previous failed result, and a transcription gets at most 3 attempts including the automatic one (then retry_limit). Free; 3 calls a minute. The analysis runs inside the request and can take minutes; if this call times out the analysis keeps going, so read it with transcriptions_get-speaker-analysis and wait: true rather than calling again. A stale revision or unfinished transcript is a 409 error, and a sourceVideoUrl that is not the transcription's own video is a 422.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Transcription id from transcriptions_create. | |
| retry | No | true to start a new attempt after a failed or timed-out one. Omit for a first analysis. Ignored while an analysis is completed or still running. | |
| revision | Yes | The transcription's revision from transcriptions_get (a 64-character hex string, present once COMPLETED). A stale one fails with 409. | |
| sourceVideoUrl | Yes | The transcription's sourceVideoUrl from transcriptions_get, unchanged; any other video is refused with 422. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: attempt accounting (max 3 including the automatic one, then retry_limit), that an in-flight or completed analysis is returned unchanged even with retry, that a new attempt overwrites a failed result, cost (free), rate limit (3/min), in-request execution time, timeout survival behavior, and the 409/422 failure conditions. These are consistent with destructiveHint=true and idempotentHint=false rather than in conflict with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then the routing rule, then constraints and failure modes; nearly every clause carries operational information. It is a single dense paragraph, though, and the rate-limit/cost/failure-code tail is packed tightly enough to be easy to skim past.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-idempotent, potentially minutes-long, attempt-limited operation with no output schema, the description covers preconditions, alternatives, retry semantics, wait strategy, quotas, and error codes. Return shape is delegated to transcriptions_get-speaker-analysis, which is the correct move given no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds real semantics on top: the attempt-limit consequences of 'retry', the staleness/409 meaning of 'revision', and the 422 refusal for a foreign 'sourceVideoUrl'. It largely echoes the schema's own error notes, so it is additive but not fully independent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('run, or retry, the speaker-to-face match') and an explicit precondition (a COMPLETED video transcription), then distinguishes itself from the sibling read tool by name. An agent can tell instantly that this initiates work rather than returning existing analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use criteria ('only when that read says unavailable with reason not_requested, or with retry: true after a failed or timed-out attempt'), names the alternative to consult first (transcriptions_get-speaker-analysis), and enumerates when not to call (audio-only, >2 minutes, >8 speakers) along with the recovery path after a timeout.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcriptions_createtranscribe a videoADestructiveInspect
Start a word-level transcription of a video or audio source and return its job id and status. Use it for general transcription, speaker analysis or timeline lipsync; for Edit Dialogue use dialogue-transcriptions_create when available. Read the result with transcriptions_get, or jobs_wait with kind transcription when available. Pass assetId to transcribe a saved VIDEO or AUDIO asset instead of a source URL. When supplying projectId, projectIntent=explicit is required: the user must explicitly ask to work in that project, select it in the interface, or this must be the project just created for this request. A matching workflow/name or an already-open editor is never permission to modify it. Default new work to a new project.
| Name | Required | Description | Default |
|---|---|---|---|
| endMs | No | End of the window to transcribe, in milliseconds from the start of the source. Omit to transcribe to the end. The window cannot exceed 60 minutes. An end past the end of the source is clamped to it, and the job reports the end it used in `sourceEndMs`. | |
| assetId | No | Saved VIDEO or AUDIO asset to transcribe; replaces sourceVideoUrl/sourceAudioUrl. | |
| startMs | No | Start of the window to transcribe, in milliseconds from the start of the source. Defaults to 0. A start at or past the end of the source video is refused with a 422 naming `startMs`. | |
| projectId | No | Optional id of a project in your organization to file the job under. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| sourceAudioUrl | No | URL of audio already extracted from the source, hosted in sync. storage. Skips the server-side audio extraction. Provide exactly one of `sourceVideoUrl` or `sourceAudioUrl`. | |
| sourceVideoUrl | No | URL of the source video, hosted in sync. storage (upload it via POST /v2/assets/upload first). Provide exactly one of `sourceVideoUrl` or `sourceAudioUrl`. | |
| maxSourceSeconds | No | Refuse the source if it is longer than this many seconds. Useful when a later step, such as a dialogue edit (10 minute window), cannot consume a longer transcript. Cannot exceed the endpoint ceiling of 3600 seconds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, idempotentHint=false and openWorldHint=true, but the description never explains what is destructive or why the call is non-idempotent. It does add genuinely useful policy context beyond the annotations — the explicit project-intent rule and the warning never to infer permission from a matching name or open editor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose, alternatives and follow-up reads are front-loaded, then the safety rule. Some redundancy: the projectIntent requirement is spelled out in both the description and the schema, costing a few sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter job-creating tool with no output schema, the description covers what is returned (job id and status), how to poll it, and the project-safety constraints. It does not mention credit/cost implications or source-size limits, which for a destructive, open-world job are meaningful omissions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with startMs/endMs windows, assetId substitution and projectIntent already documented in the schema. The description restates the projectId/projectIntent coupling and the assetId alternative but adds little syntax or constraint detail beyond what structured fields provide; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb and resource ("Start a word-level transcription of a video or audio source") plus the return shape (job id and status). It also names the sibling it is not (dialogue-transcriptions_create for Edit Dialogue), so an agent can discriminate without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: use this for general transcription, speaker analysis or timeline lipsync; use dialogue-transcriptions_create for Edit Dialogue; read results via transcriptions_get or jobs_wait. It also states when to pass assetId instead of a source URL and the conditions that permit a projectId.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcriptions_getread a transcriptionARead-onlyInspect
Read one transcription job by id. Returns:
status: PENDING, PROCESSING, COMPLETED or FAILED.
Once COMPLETED, transcript.segments, each with an id and words. A word has text, startMs and endMs in milliseconds from the start of the source (not of the transcribed window), and a speakerId that is null or absent when unknown.
speakerCount, a top-level field beside transcript.
revision (once there is a transcript) and sourceVideoUrl (null for an audio source), which transcriptions_analyze-speakers takes.
On FAILED, error.code. NO_AUDIO, NO_AUDIO_TRACK and SOURCE_TOO_LONG will not succeed on retry.
While running, estimate.estimatedFinishAt may give an expected finish. estimate is null or absent when there is too little history. Use it after transcriptions_create. id is the UUID that call returned: a malformed id is a 400 error, and a well-formed id not in the current organization is a 404. With wait: true the server keeps reading for up to about 50 seconds and returns once the job is COMPLETED or FAILED. If it is still running, call again with wait: true; never start another transcription to check progress. Not for Edit Dialogue transcriptions (dialogue-transcriptions_get, when available) or face matches (transcriptions_get-speaker-analysis). jobs_get and jobs_wait with kind transcription, when available, read the same job with the cross-kind statuses.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Transcription id from transcriptions_create. | |
| wait | No | Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a safe read-only operation, and the description adds substantial behavioral context beyond them: job status lifecycle, failure codes that will not succeed on retry, 400 versus 404 meanings for the id, and the roughly 50-second server-side wait behavior. It also warns against starting another transcription to check progress.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence, and the remaining details are organized into a bulleted return-shape section followed by usage caveats. Despite its length, every section supplies information the agent needs, particularly because there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of explaining return values, and it does so thoroughly: status values, segment and word structure, speakerCount, revision, sourceVideoUrl, error.code, and estimate behavior. It also covers the wait lifecycle and the relevant alternatives.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters well. The description still adds useful semantics by explaining that a malformed id produces a 400 and an id outside the organization produces a 404, and by clarifying the retry pattern for wait: true.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read one transcription job by id.' It explicitly distinguishes this tool from dialogue-transcriptions_get, transcriptions_get-speaker-analysis, and the cross-kind jobs_get/jobs_wait alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use the tool ('Use it after transcriptions_create'), when not to use it (Edit Dialogue transcriptions, face matches), and what to do when a waited job is still running. The guidance is explicit enough that an agent can choose correctly without inspecting sibling schemas.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcriptions_get-speaker-analysisread which face belongs to each speakerARead-onlyInspect
Read which face in the video belongs to each transcript speaker of a COMPLETED video transcription, by transcription id. Read-only: video transcriptions of your own media are usually analysed automatically, and transcriptions_analyze-speakers starts or retries an analysis only when this returns unavailable with reason not_requested, analysis_failed or analysis_timeout. Returns status (processing, completed or unavailable), the revision that transcriptions_slice-speaker-face-track needs, and speakers: each matched (with an avatar, the evidence and a faceTrack whose url is a public JSON file with one box per frame of the source file where that face is visible) or uncertain (with a reason). Other unavailable reasons do not call for analyze-speakers: retry_limit means the attempts are used up, and reasons such as source_binding_unavailable (an audio-only source or one outside your organization's storage), source_too_long or too_many_speakers rule the source out. wait: true waits for the analysis, not the transcription; jobs_wait with kind speaker_analysis, when available, waits on the same analysis. Next step for lipsync_create-timeline: cut each matched speaker's track per clip with transcriptions_slice-speaker-face-track. Clips of an uncertain speaker use speaker detect instead, or lipsync: false where the timeline tool offers that field.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Transcription id from transcriptions_create. | |
| wait | No | Wait on the server while the analysis status is processing, for up to about 50 seconds, then return its latest state; if still processing, call again with wait: true instead of sleeping. Does not wait for an unfinished transcription, which returns 409. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint/openWorldHint=false, and the description goes well beyond them: it discloses the three status values, the revision field, the structure of matched vs uncertain speakers, the faceTrack URL format (public JSON, one box per frame), and the failure reason taxonomy. It also clarifies that wait waits on the analysis rather than the transcription, which is a subtle behavioral distinction an agent would otherwise get wrong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and scope, then the conditional routing, then the return shape, then the next step — a sensible order with no filler sentences. It is dense and long, and the slice-speaker-face-track guidance appears in both the return-value and next-step sentences, which is slight redundancy but each occurrence serves a different point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description fully describes the response envelope (status, revision, speakers with matched/uncertain branches and their fields), so an agent knows exactly what it will receive. Combined with the error-reason routing and the named downstream tool, nothing needed to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented in the schema, including the ~50s wait semantics and the 409 on unfinished transcription. The description adds real meaning beyond that by contrasting wait here with jobs_wait with kind speaker_analysis, making the wait target unambiguous; the id parameter itself gets no extra semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: read which face belongs to each transcript speaker, by transcription id, for a COMPLETED transcription. It explicitly distinguishes itself from the two most confusable siblings, transcriptions_analyze-speakers (which starts/retries an analysis) and transcriptions_slice-speaker-face-track (the downstream consumer of the returned revision).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when/when-not routing: normally the analysis runs automatically, so only call analyze-speakers when this returns unavailable with reason not_requested, analysis_failed or analysis_timeout, and it names the other unavailable reasons (retry_limit, source_binding_unavailable, source_too_long, too_many_speakers) that do NOT warrant a retry. It also routes uncertain speakers to speaker detect or lipsync: false, and points to jobs_wait for the same analysis.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcriptions_slice-speaker-face-trackcut a clip's face trackADestructiveInspect
Cut one matched speaker's face track to the frames of one lipsync_create-timeline clip and return {url}: a public JSON file of per-frame face boxes to pass as that clip's speaker.faceTrackUrl, so the clip lipsyncs exactly that person. Use it after transcriptions_get-speaker-analysis reports the speaker matched; not for uncertain speakers (a 422 error), whose clips use speaker detect or a point on the face instead. Frames are [startFrame, endFrame) counted from the first frame of the source file, not of the transcription window, and the track is resampled by time onto your fps. Each call writes a new file and returns a new url; it is free, 60 calls a minute. url is null, and no file is written, when the face is on none of those frames: use detect for that clip, or keep it unlipsynced with lipsync: false where lipsync_create-timeline offers that field. A changed transcript revision is a 409 error: read the analysis again.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Transcription id from transcriptions_create. | |
| fps | Yes | Frame rate of the video the timeline lipsyncs, as assets_get-playback-metadata reports it; the face track is resampled by time onto this grid. | |
| skip | No | Optional range { startFrame, endFrame } (end exclusive) strictly inside the clip that a cut removed from its footage. Those frames are left out of the file, so it keeps one box per remaining frame. Usually omitted. | |
| endFrame | Yes | Frame after the clip ends (exclusive): the timeline clip endFrame + 1. | |
| revision | Yes | The revision returned by transcriptions_get-speaker-analysis, so the call matches that analysis. | |
| speakerId | Yes | A matched speaker id from transcriptions_get-speaker-analysis. | |
| startFrame | Yes | First frame of the clip, inclusive, counted from the first frame of the source file: the timeline clip's startFrame. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations it discloses the cost profile ('it is free, 60 calls a minute'), the side effect ('each call writes a new file and returns a new url', i.e. no overwrite despite destructiveHint), the null/no-file outcome, and two failure modes (422 for uncertain speakers, 409 for a changed transcript revision). What is missing is only the shape of the produced file beyond 'per-frame face boxes'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and primary return value, then constraints, then error paths — a sensible order with no filler sentences. It runs long and repeats the frame-origin rule that the schema already states for startFrame/endFrame, which keeps it just short of exemplary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-parameter, non-idempotent, open-world write tool with no output schema, the description covers purpose, prerequisite, return value, null case, rate limit and both error codes. An agent could call it and handle its outcomes correctly without further documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics: the frame range is half-open, counted from the first frame of the source file rather than the transcription window, and the track is resampled by time onto the caller's fps. The optional 'skip' parameter is still only explained in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Cut one matched speaker's face track to the frames of one lipsync_create-timeline clip') and names the exact return artifact ({url} JSON of per-frame face boxes for speaker.faceTrackUrl). That is enough to tell it apart from transcriptions_get-speaker-analysis and from the 'speaker detect' alternative without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite ('Use it after transcriptions_get-speaker-analysis reports the speaker matched'), an explicit exclusion ('not for uncertain speakers (a 422 error)') and the alternative to use instead ('speaker detect or a point on the face'). It also handles the empty-result branch by naming the fallbacks (detect, or lipsync: false).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
translation-previews_createtranslate audio for previewADestructiveInspect
Start one paid job that translates a saved audio asset's speech into another language, producing translated audio the user can review before a separate lip-sync. Use it when the user wants to hear the translation first or place the audio on a timeline; for a finished dubbed video in one step use dubbing_create, and for speech from a script use speech-previews_create. Confirm the source audio, target language and the translation-previews_estimate quote with the user first. It needs a project: for new work call projects_create (defaultWorkflow translate_and_dub) and pass that id with projectIntent=explicit; use an existing project only when the user explicitly selected it, never because of a matching name or open editor. Persist one UUID idempotencyKey before calling and, after an uncertain response, resend the identical request with it; a new key bills again. Returns the job (id, status, outputMediaUrl once done, error, recoveryRequired); follow it with translation-previews_get wait: true, or jobs_wait kind translation_preview when available. Never translate again because attaching the output failed or recoveryRequired is true. Lip-syncing the translated audio is a separate, explicitly approved lipsync_create or lipsync_create-timeline call, not dubbing_create.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project for the job: one just created with projects_create for this request, or one the user explicitly selected; pass projectIntent=explicit with it. Use the same id for translation-previews_get. | |
| sourceLang | No | Optional and usually omitted: the source language is detected (sent as auto). | |
| targetLang | Yes | Language code to translate into, from dubbing_get-options targetLanguages (for example es or pt-BR). | |
| audioAssetId | Yes | Saved AUDIO asset to translate, such as one from assets_create (type=AUDIO), assets_list or audio-trims_create; the same asset you quoted with translation-previews_estimate. | |
| projectIntent | No | Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor. | |
| idempotencyKey | Yes | A new UUID saved before the call. Reuse it with identical input only to recover an uncertain response. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false and openWorldHint=true, but the description adds material context: this is a paid job, a new idempotencyKey bills again, an uncertain response must be retried with the identical key, and translation must not be repeated when attaching the output failed or recoveryRequired is true. That is real cost and recovery disclosure beyond the flags. It stops short of stating rate limits or permissions, hence not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and scope are front-loaded in the first sentence, and nearly every subsequent sentence carries an operational constraint rather than filler. It is dense — a single long paragraph mixing routing, project rules, idempotency and recovery — so a slight structural cost, but the length is justified by the tool's cost and complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paid, destructive, multi-step job tool the description covers prerequisites, project provenance, idempotency protocol, return shape and recovery paths. It even summarizes the return fields (id, status, outputMediaUrl, error, recoveryRequired) despite an output schema existing, which is redundant but harmless and reinforces the polling handoff.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds workflow-level meaning: idempotencyKey must be persisted before the call and reused only for recovery, and projectIntent=explicit must accompany the project id with a prohibition on inferring intent from matching names or an open editor. Those behavioral constraints go beyond what the property descriptions convey on their own.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Start one paid job that translates a saved audio asset's speech into another language') plus the output ('translated audio the user can review before a separate lip-sync'). It explicitly names the two siblings it is not — dubbing_create for one-step dubbed video and speech-previews_create for script-based speech — so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('user wants to hear the translation first or place the audio on a timeline') and when-not (one-step dubbing), plus prerequisites: confirm source audio, target language and the estimate quote; create a project via projects_create with defaultWorkflow translate_and_dub; use an existing project only on explicit user selection. It also routes follow-up to translation-previews_get wait:true and jobs_wait, and states that lip-syncing is a separate approved call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
translation-previews_estimateestimate translated audio previewARead-onlyIdempotentInspect
Quote translating one saved audio asset with translation-previews_create, before creating it. Use it to price a translated-audio preview; for a full video dub, quote dubbing_create with generations_estimate-cost workflow=translate-and-dub instead. Read-only and free: it does not translate, create a job, trim or modify the audio, or incur provider charges. Pass the same projectId, audioAssetId and organizationId you will pass to translation-previews_create, so the quote matches the job that gets billed.
Returns billing (sync_credits, sync_usd, included, or external, meaning provider charges outside sync. that you must disclose separately), estimatedGenerationCost and estimatedCredits (either may be null), and preview durations.
If preview.quotedDurationSeconds is shorter than sourceDurationSeconds, the source exceeds limitSeconds, the free plan's dubbing duration limit (a paid plan lifts it), and only that bounded part was quoted. Explain the limit and offer the bounded preview, but never submit the original: translation-previews_create refuses it instead of trimming it. Save a shorter copy as a new audio asset (audio-trims_create, when listed, with durationSeconds up to limitSeconds), then quote and create with that asset.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project the translation belongs to, from projects_create or projects_list. | |
| audioAssetId | Yes | Saved AUDIO asset to quote, such as one from assets_create (type=AUDIO), assets_list or audio-trims_create; the same asset translation-previews_create will translate. | |
| organizationId | No | Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description partly restates that ('does not translate, create a job, trim or modify the audio'), but it adds real context annotations cannot carry: no provider charges, the free-plan limitSeconds bound, that only a bounded part is quoted, and that create refuses over-limit sources rather than trimming them. The 'external' billing meaning is also explained. Good depth, with a little redundancy against the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the alternative, then the read-only guarantee, then the returned fields, then the duration-limit edge case. Dense but every paragraph carries distinct information; the only waste is a mild restatement of the read-only annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still frames what the quote returns (billing modes, estimated costs, durations) and — crucially — explains the ambiguous case where quotedDurationSeconds is shorter than sourceDurationSeconds. Prerequisites, alternatives and failure behavior are all covered, so nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds cross-call semantics the schema does not state: pass the same projectId, audioAssetId and organizationId as translation-previews_create so the quote matches the job that gets billed. That consistency requirement is genuinely new information beyond field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb and resource: 'Quote translating one saved audio asset', and names the operation it precedes (translation-previews_create). It also explicitly separates itself from the full-dub path (dubbing_create / generations_estimate-cost), so an agent can route without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('price a translated-audio preview'), an explicit alternative for a different need ('for a full video dub, quote dubbing_create with workflow=translate-and-dub'), and an explicit do-not ('never submit the original'). The recovery path — save a shorter copy with audio-trims_create, then quote that asset — is spelled out step by step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
translation-previews_getread translated audio previewARead-onlyIdempotentInspect
Read one translated-audio preview job by id: status (PENDING, PROCESSING, COMPLETING while the finished audio is attached, then COMPLETED or FAILED), source and target languages, error, recoveryRequired, and once COMPLETED outputMediaUrl and outputDurationSec. Use it to follow a translation-previews_create job; jobs_get and jobs_wait with kind translation_preview, when available, read the same job through the generic job tools. Pass wait: true to hold on the server for up to about 50 seconds until the job finishes or recoveryRequired is set; if it is still running, call again. Read-only: it never starts, retries or bills a translation. On FAILED, report error.message; another attempt is a new paid translation-previews_create the user must approve. recoveryRequired means provider acceptance is uncertain and only sync. can resolve it: do not create another job. Once COMPLETED, register outputMediaUrl with assets_create (type=AUDIO) or pass it as a clip audioUrl to lipsync_create-timeline for the separate lip-sync step.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Translation preview id from translation-previews_create. | |
| wait | No | Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping. | |
| projectId | Yes | The projectId passed to translation-previews_create for this job. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/idempotentHint annotations, it discloses the state machine (PENDING → PROCESSING → COMPLETING → COMPLETED/FAILED), the server-side wait window of about 50 seconds, and the 'call again' pattern. It also flags billing semantics (never starts, retries or bills), the meaning of recoveryRequired, and how to resolve it via sync, which is decision-critical behavior not encoded in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose and the status lifecycle, then the alternatives, then the wait behavior, then error handling and next steps — a logical order for an agent. It is dense and long for a getter, but each sentence carries actionable routing or state information rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still summarizes the key result fields and, critically, tells the agent what to do with outputMediaUrl once COMPLETED (assets_create type=AUDIO or lipsync_create-timeline). For a polling job-status tool with three parameters, that covers everything needed to call it and act on the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so id, wait and projectId are already documented in the schema, and the description's wait explanation largely restates the schema's own wording. It adds some framing by tying wait to the follow-a-job workflow, but no format, bounds or semantics the schema lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Read one translated-audio preview job by id") and enumerates the returned state fields (status, languages, error, recoveryRequired, outputMediaUrl, outputDurationSec). It explicitly distinguishes itself from the generic job tools (jobs_get / jobs_wait with kind translation_preview) rather than leaving sibling selection ambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the primary case (follow a translation-previews_create job), names the alternatives that read the same job, and states exclusions: on FAILED another attempt is a new paid translation-previews_create requiring approval, and on recoveryRequired no new job may be created. The wait:true polling loop is spelled out with a fallback action, so nothing critical is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voices_listlist voicesARead-onlyInspect
List the text-to-speech voices this organization can use: premade ElevenLabs voices plus voices it has cloned, each with id, name, provider, previewUrl and restriction. Use it when speech comes from a script: for "make this image/video say X", pass a returned id (not the provider voiceId) as voiceId to lipsync_create with script, or to speech-previews_create. Check it for an existing clone before cloning a voice again. A voice whose restriction is set cannot synthesize speech; choose another. Not for lipsync models; use models_list. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | Return only voices from this provider. Only elevenlabs is accepted; omit to list every voice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=false and destructiveHint=false, so safety is covered; the description adds genuinely new behavioral detail that a voice with a non-null restriction cannot synthesize speech and must be avoided. It also clarifies the id-vs-provider-voiceId distinction, which prevents a likely misuse. The trailing 'Read-only.' merely restates the annotation, so it earns no credit but does no harm.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose and the returned fields before the usage directives, and every clause carries actionable information (id fidelity, clone check, restriction rule, sibling exclusion). It is dense and somewhat run-on, packing several directives into one long sentence, but there is little filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only list tool with no output schema, the definition covers purpose, filtering, returned fields, downstream id usage, and the restriction edge case. Nothing an agent needs to call it correctly or interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single enum parameter is fully documented in-schema ('Only elevenlabs is accepted; omit to list every voice'). The description mentions provider voices but adds no filtering semantics beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List the text-to-speech voices') plus scope ('this organization can use: premade ElevenLabs voices plus voices it has cloned') and enumerates the returned fields. It also explicitly excludes adjacent resources ('Not for lipsync models; use models_list'), so an agent can separate it from siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete when-to-use triggers ('when speech comes from a script'), names the downstream tools to pass ids to (lipsync_create, speech-previews_create), warns to check for an existing clone before cloning again, and provides an in-tool exclusion rule for voices whose restriction is set. It also names models_list as the alternative for lipsync models.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
47 tool updates
v0.2.4- Changed
assets_count7 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"Ignored when counting."New value: +"No effect on the count; omit it." - changed
Input schema / properties / limit / descriptionPrevious value: -"Ignored when counting."New value: +"No effect on the count; omit it. If sent, it must be an integer from 1 to 100 or the call fails validation." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Only assets attached to this project (an id from projects_list or projects_create)."New value: +"Only assets attached to this project: a project UUID from projects_list or projects_create." - changed
Input schema / properties / searchQuery / descriptionPrevious value: -"Text to match against names."New value: +"Case-insensitive text matched anywhere in the asset name." - changed
Input schema / properties / sortBy / descriptionPrevious value: -"Sort order, such as dateDesc for newest first."New value: +"No effect on the count; omit it." - changed
Input schema / properties / types / descriptionPrevious value: -"Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list."New value: +"Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list; an asset of any listed type matches." - changed
Input schema / properties / userId / descriptionPrevious value: -"Only assets created by this user id."New value: +"Only assets created by this user: a user UUID."
- Changed
assets_create8 fields changed- changed
Input schema / properties / contentSha256 / descriptionPrevious value: -"Optional SHA-256 hex digest of the file."New value: +"Optional lowercase hex SHA-256 digest of the file's bytes." - changed
Input schema / properties / name / descriptionPrevious value: -"Display name for the asset."New value: +"Display name for the asset. Not used for a social link, which is named after the video." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Project to attach the asset to, from projects_create or projects_list."New value: +"Project to attach the asset to; send it with projectIntent=explicit. Returns 422 if it is not a project you can use in this organization." - changed
Input schema / properties / size / descriptionPrevious value: -"File size in bytes, when known."New value: +"File size in bytes, when known. For a sync. upload the stored file's measured size is used instead." - changed
Input schema / properties / type / descriptionPrevious value: -"Media type: VIDEO, AUDIO or IMAGE."New value: +"Media type: VIDEO, AUDIO or IMAGE. Send VIDEO for a social video link; its import always saves a VIDEO asset." - changed
Input schema / properties / url / descriptionPrevious value: -"Media URL: the url assets_create-upload-url returned, a public https:// file, or a YouTube, TikTok, Instagram or Facebook video link."New value: +"Media URL: a public https:// file, the url (not the uploadUrl) that assets_create-upload-url returned once the PUT finished, or a YouTube, TikTok, Instagram or Facebook video link." - changed
Input schema / properties / visibility / descriptionPrevious value: -"USER keeps it private to you; ORGANIZATION shares it with your team."New value: +"USER (default) or ORGANIZATION, which shares the asset with everyone in the organization. A USER asset is still visible across the organization when attached to a project shared with the organization. Not used for a social link." - changed
Input schema / properties / wait / descriptionPrevious value: -"Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping."New value: +"Social link only: the server repeats the identical request every retryAfterMs (15 seconds if absent) until an attempt returns the saved asset or about 50 seconds pass. If no attempt got the asset, even when the import finished just after the last attempt, the call returns the 409 import_in_progress; call again with wait: true."
- Changed
assets_create-upload-url3 fields changed- changed
Input schema / properties / contentType / descriptionPrevious value: -"MIME type of the file, such as video/mp4; send the same value when you PUT it."New value: +"MIME type starting with audio/, video/ or image/, such as video/mp4; send the same value as the Content-Type header on the PUT." - changed
Input schema / properties / fileName / descriptionPrevious value: -"Name of the local file, with its extension."New value: +"Name of the local file with its extension, up to 255 characters. It only names the stored file: the extension is kept (lowercased), spaces become underscores and other special characters may be dropped." - changed
Input schema / properties / size / descriptionPrevious value: -"File size in bytes."New value: +"Exact file size as a whole number of bytes, up to 5GB; the PUT must send exactly this many bytes. Your plan's size limit is checked against it here, and again by assets_create on the uploaded file."
- Changed
assets_get1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Asset id from assets_list."New value: +"Asset id (UUID) from assets_list, or the id assets_create returned; a generation or project id returns 404."
- Changed
assets_get-download-url1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Asset id from assets_list."New value: +"Asset id (UUID) from assets_list or assets_get, not a generation id; for a generation's output use its outputMediaUrl from generations_get."
- Changed
assets_get-playback-metadata1 field changed- changed
Input schema / properties / assetId / descriptionPrevious value: -"Asset id from assets_list."New value: +"Asset id (UUID) from assets_list or assets_get."
- Changed
assets_list7 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"The previous page's nextCursor, to read the next page. Omit for the first page."New value: +"The nextCursor from the previous page; send the same filters and sortBy with it. Omit for the first page." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results to return. Keep it small and page with cursor."New value: +"Page size, an integer from 1 to 100 (default 10); other values fail validation. Keep it small and page with cursor." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Only assets attached to this project (an id from projects_list or projects_create)."New value: +"Only assets attached to this project: a project UUID from projects_list or projects_create." - changed
Input schema / properties / searchQuery / descriptionPrevious value: -"Text to match against names."New value: +"Case-insensitive text matched anywhere in the asset name." - changed
Input schema / properties / sortBy / descriptionPrevious value: -"Sort order, such as dateDesc for newest first."New value: +"Sort order (default nameAsc). dateAsc and dateDesc sort by creation time, kindAsc and kindDesc by file format; duration, size and kind sorts put missing values last." - changed
Input schema / properties / types / descriptionPrevious value: -"Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list."New value: +"Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list; an asset of any listed type matches." - changed
Input schema / properties / userId / descriptionPrevious value: -"Only assets created by this user id."New value: +"Only assets created by this user: a user UUID."
- Changed
assets_update8 fields changed- changed
Input schema / properties / durationSeconds / descriptionPrevious value: -"Media length in seconds, when known."New value: +"Corrected media length in seconds, greater than 0. Later duration checks read this value, so send only a length you have verified." - changed
Input schema / properties / format / descriptionPrevious value: -"File format or extension, such as mp4 or wav, when known."New value: +"Corrected file format or extension, such as mp4 or wav; must not be empty. Send only a verified correction." - changed
Input schema / properties / height / descriptionPrevious value: -"Video or image height in pixels, when known."New value: +"Corrected height in pixels, a positive whole number. Send only a verified correction." - changed
Input schema / properties / id / descriptionPrevious value: -"Asset id from assets_list."New value: +"Asset id (UUID) from assets_list or assets_get." - changed
Input schema / properties / name / descriptionPrevious value: -"New display name."New value: +"New display name; must not be empty." - changed
Input schema / properties / size / descriptionPrevious value: -"File size in bytes, when known."New value: +"Corrected file size in bytes, a positive whole number. Send only a verified correction." - changed
Input schema / properties / visibility / descriptionPrevious value: -"USER keeps it private to you; ORGANIZATION shares it with your team."New value: +"USER: visible to its creator, to everyone in the organization when the asset is attached to an ORGANIZATION-visible project, and to organization API keys with no owner. ORGANIZATION: visible to everyone in the organization." - changed
Input schema / properties / width / descriptionPrevious value: -"Video or image width in pixels, when known."New value: +"Corrected width in pixels, a positive whole number. Send only a verified correction."
- Changed
audio-trims_create1 field changed- changed
Input schema / properties / assetId / descriptionPrevious value: -"Saved AUDIO asset to shorten."New value: +"Saved AUDIO asset to shorten, from assets_list or assets_create. Required in practice; audioAssetId is only its deprecated alias."
- Changed
audio-trims_get1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Audio trim id from audio-trims_create."New value: +"The id that audio-trims_create returned (a UUID). Poll with this same id until the trim is completed or failed."
- Changed
batches_get1 field changed- changed
Input schema / properties / wait / descriptionPrevious value: -"Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping."New value: +"Poll until the batch is COMPLETED or FAILED or about 50 seconds pass, then return its latest state; reading a finished batch's result file can take up to 30 seconds more. If it is still running, call again with wait: true instead of sleeping."
- Changed
batches_list3 fields changed- changed
Input schema / properties / createdAfter / descriptionPrevious value: -"ISO 8601 date-time."New value: +"Only batches created after this ISO 8601 date-time, such as 2026-11-06T00:00:00Z. Set it just before an uncertain batches_create to spot that batch." - changed
Input schema / properties / createdBefore / descriptionPrevious value: -"ISO 8601 date-time."New value: +"Only batches created before this ISO 8601 date-time, such as 2026-11-07T00:00:00Z." - changed
Input schema / properties / status / descriptionPrevious value: -"Only batches in this status, such as PROCESSING for batches still running."New value: +"Only batches in this status. PENDING, JOBS_CREATED and PROCESSING all mean still running; COMPLETED and FAILED mean done."
- Changed
dialogue_upload-source2 fields changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the Edit Dialogue work belongs to, from projects_create."New value: +"Project the copy is saved in: the id projects_create returned for this request (defaultWorkflow edit_dialogue), or a project the user explicitly chose." - changed
Input schema / properties / videoAssetId / descriptionPrevious value: -"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."New value: +"Saved VIDEO asset to copy, from assets_create or assets_list. Must be accessible to the connected account."
- Changed
dialogue-previews_create4 fields changed- changed
Input schema / properties / edits / descriptionPrevious value: -"User-approved changes/removals referencing timed word IDs in the source transcript."New value: +"The complete list of user-approved changes/removals for this preview (1 to 100), including earlier ones to keep when revising. Word ids come from the COMPLETED transcription's transcript, or from the previous preview's sourceTranscript, never its resultTranscript." - changed
Input schema / properties / previousPreviewId / descriptionPrevious value: -"Completed or partially completed preview ID for this source when reopening. Supply exactly one of previousPreviewId or transcriptionJobId."New value: +"Id of a COMPLETED or COMPLETED_PARTIAL preview of this source, to revise it. Its sourceTranscript and cloned voice are reused, but its edits are not carried over, so edits must be the full set you want; sending the same edits again reruns it. Supply exactly one of previousPreviewId or transcriptionJobId." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Accessible Sync project for the preview. Keep unchanged on retries."New value: +"Project for the preview, the one used for the transcription. Keep unchanged on retries. Default new work to a new project: the id projects_create returned for this request (defaultWorkflow edit_dialogue). Use an existing project only when the user explicitly chose it, and then pass projectIntent=explicit." - changed
Input schema / properties / transcriptionJobId / descriptionPrevious value: -"Completed transcription ID for this source. Supply exactly one of transcriptionJobId or previousPreviewId."New value: +"Id from dialogue-transcriptions_create, for a first preview; that transcription must be COMPLETED. Supply exactly one of transcriptionJobId or previousPreviewId."
- Changed
dialogue-previews_get3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Preview id from dialogue-previews_create."New value: +"The id returned by dialogue-previews_create." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the Edit Dialogue work belongs to, from projects_create."New value: +"The projectId used with dialogue-previews_create." - changed
Input schema / properties / videoAssetId / descriptionPrevious value: -"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."New value: +"The videoAssetId used to create this preview (the copy's id if dialogue-transcriptions_create returned one). A preview made from a different source video is rejected."
- Changed
dialogue-transcriptions_create2 fields changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the Edit Dialogue work belongs to, from projects_create."New value: +"Project for this Edit Dialogue work: the id projects_create returned for this request (defaultWorkflow edit_dialogue) or a project the user explicitly chose; pass projectIntent=explicit with either. The tool reads it first to confirm access, and the copy fallback saves into it. Keep it for every later dialogue call." - changed
Input schema / properties / videoAssetId / descriptionPrevious value: -"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."New value: +"Saved VIDEO asset to transcribe that the account can read, from assets_create, assets_list or dialogue_upload-source. If the result returns videoAssetId, that sync.-hosted copy replaces this id for every later dialogue call."
- Changed
dialogue-transcriptions_get3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Transcription id from dialogue-transcriptions_create."New value: +"The id field of the dialogue-transcriptions_create result; later passed to dialogue-previews_create as transcriptionJobId." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the Edit Dialogue work belongs to, from projects_create."New value: +"The projectId passed to dialogue-transcriptions_create. Used only to confirm project access; the job itself is read by id." - changed
Input schema / properties / videoAssetId / descriptionPrevious value: -"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."New value: +"The videoAssetId passed to dialogue-transcriptions_create, or the copy's id when its result returned videoAssetId. It must be a VIDEO asset; its stored URL is compared with the job's source, and a job made from a different source video is rejected."
- Changed
dialogue-videos_create1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Accessible Sync project for the new output. Keep unchanged on retries."New value: +"Project for the new output, the one used for the preview. Keep unchanged on retries. Default new work to a new project: the id projects_create returned for this request (defaultWorkflow edit_dialogue). Use an existing project only when the user explicitly chose it, and then pass projectIntent=explicit."
- Changed
dialogue-videos_estimate2 fields changed- changed
Input schema / properties / dialogueEditId / descriptionPrevious value: -"Id of the completed, user-approved preview from dialogue-previews_create."New value: +"Id of the COMPLETED or COMPLETED_PARTIAL preview from dialogue-previews_create that the user approved; not a transcription or generation id." - changed
Input schema / properties / model / descriptionPrevious value: -"Lipsync model name from models_list, such as sync-3."New value: +"Lipsync model name from models_list, such as sync-3. Use the same model on dialogue-videos_create."
- Changed
dubbing_create7 fields changed- changed
Input schema / properties / continuation / descriptionPrevious value: -"Only when the user explicitly continues an existing generation in this project: the parent generation and its workflow."New value: +"Only when the user explicitly continues an existing generation in this project: the parent generation (from generations_get-continuation) and its workflow, which must be translate_and_dub. Requires projectId." - changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Persist one unique key per approved generation. Retry an uncertain request with this exact key and unchanged inputs; never automatically create a new key."New value: +"Persist one unique key per approved generation before calling. Retry an uncertain request with this exact key, the same projectCreationKey and unchanged inputs; never automatically create a new key." - changed
Input schema / properties / model / descriptionPrevious value: -"Video lip-sync model returned by models_list."New value: +"Lip-sync model name from models_list (for example sync-3), used for the final render. Any generations_estimate-cost quote for this dub must use the same model." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Project ID only when explicitly selected by the user, or just created for this request. Otherwise omit it to create a new project. Keep unchanged on retries."New value: +"Project ID only when explicitly selected by the user, or just created for this request; requires projectIntent=explicit. Cannot be combined with projectName or projectCreationKey. Otherwise omit it to create a new project. Keep unchanged on retries." - changed
Input schema / properties / projectName / descriptionPrevious value: -"Name for a NEW project. A matching existing name is never reused."New value: +"Name for the NEW project created when projectId is omitted; defaults to \"Translate and Dub\". Cannot be combined with projectId. A matching existing name is never reused." - changed
Input schema / properties / sourceLang / descriptionPrevious value: -"Spoken language of the source video. Leave as auto to detect it."New value: +"Spoken language of the source video, from dubbing_get-options sourceLanguages. Defaults to auto, which detects it; set a code only when the user names the source language." - changed
Input schema / properties / targetLang / descriptionPrevious value: -"Target language from the API-supported list."New value: +"Language code to dub into, for example es or pt-BR; the same list dubbing_get-options returns as targetLanguages."
- Changed
feedback_send1 field changed- changed
Input schema / properties / kind / descriptionPrevious value: -"confusing_error: an error that did not say what to fix. bug: wrong result or crash. missing_capability: a tool or option you needed. workaround: you had to do extra steps. docs: a description that misled you."New value: +"confusing_error: an error that did not say what to fix. bug: wrong result or crash. missing_capability: a tool or option you needed. workaround: you had to do extra steps. docs: a description that misled you. other: friction that fits none of these."
- Changed
generations_estimate-cost4 fields changed- changed
Input schema / properties / model / descriptionPrevious value: -"Model name from models_list, such as sync-3."New value: +"Model name from models_list, such as sync-3; use the same model the create call will use." - changed
Input schema / properties / syncMode / descriptionPrevious value: -"The same sync_mode selected for generation. For videos, cut_off uses the shorter input and silence the longer input. Images and other modes follow replacement audio duration."New value: +"The sync_mode the generation will use; only valid alongside script or audioDuration. For a video, cut_off bills the shorter of speech and videoDuration and silence the longer; images and other modes follow the speech length." - changed
Input schema / properties / videoDuration / descriptionPrevious value: -"Source video duration in seconds, used with syncMode to account for cut_off or silence. Omit for an image."New value: +"Source video length in seconds. Needed with syncMode cut_off or silence when quoting script or audioDuration for a video; only valid alongside script or audioDuration, and rejected for an image." - changed
Input schema / properties / workflow / descriptionPrevious value: -"Omit for lip-sync only. translate-and-dub includes dubbing and lip-sync, estimated using the source duration. Actual output duration may differ."New value: +"translate-and-dub prices dubbing plus lip sync from the source duration in duration, and returns a breakdown with external provider charges excluded; it rejects script and audioDuration. Omit for lip sync only."
- Changed
generations_get2 fields changed- changed
Input schema / properties / timeout / descriptionPrevious value: -"Maximum seconds to block when wait=true (1-10). Default 5."New value: +"Seconds each read holds (1-10). Leave it out; wait: true reads for about 50 seconds." - changed
Input schema / properties / wait / descriptionPrevious value: -"Explicitly long-poll until the generation reaches a terminal state (COMPLETED, FAILED, REJECTED) or the timeout elapses. On timeout the current state is returned with HTTP 200 - check `status` and retry. Cannot be combined with include=progress."New value: +"Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping."
- Changed
generations_get-continuation1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the generation belongs to."New value: +"The generation's own project id."
- Changed
generations_get-costs1 field changed- changed
Input schema / properties / generationId / descriptionPrevious value: -"Existing Sync generation ID returned by generation creation or history tools."New value: +"Id of the past generation, as returned by the create tool, generations_list or projects_list-generations."
- Changed
generations_list1 field changed- changed
Input schema / properties / status / descriptionPrevious value: -"Filter generations by status"New value: +"Only generations in this status: PENDING, PROCESSING, COMPLETED, FAILED or REJECTED. PENDING (queued) and PROCESSING both mean still running, so check both before concluding nothing is in progress."
- Added
jobs_create-many - Changed
jobs_get1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"The job to read; see the tool description per kind."New value: +"The job id for the chosen kind, as listed in the tool description; for import it is the social video link itself."
- Added
jobs_get-many - Changed
jobs_wait1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"The job to read; see the tool description per kind."New value: +"The job id for the chosen kind, as listed in the tool description; for import it is the social video link itself."
- Changed
lipsync_create3 fields changed- changed
Input schema / properties / audioAssetId / descriptionPrevious value: -"Existing Sync asset ID in the same organization."New value: +"Saved audio asset id in the same organization as this call, from assets_list or assets_create when available. Supply audio or script, not both." - changed
Input schema / properties / imageAssetId / descriptionPrevious value: -"Existing Sync asset ID in the same organization."New value: +"Saved still image asset id in the same organization as this call, from assets_list or assets_create when available, for image-to-video lipsync. Supply exactly one visual input." - changed
Input schema / properties / videoAssetId / descriptionPrevious value: -"Existing Sync asset ID in the same organization."New value: +"Saved video asset id in the same organization as this call, from assets_list or assets_create when available. Supply exactly one visual input."
- Changed
lipsync_create-timeline1 field changed- changed
Input schema / properties / clips / descriptionPrevious value: -"Clips placed on the video, in any order, without overlapping. Parts no clip covers keep their original picture and sound; clips with lipsync: false keep their picture but play outputAudio."New value: +"Clips placed on the video, in any order, without overlapping. Parts no clip covers keep their original picture, and their original sound unless outputAudio plays; clips with lipsync: false keep their picture but play outputAudio."
- Changed
projects_create3 fields changed- changed
Input schema / properties / defaultWorkflow / descriptionPrevious value: -"Default top-level creator workflow for this project."New value: +"The workflow the user asked for, such as translate_and_dub for translation, lipsync for lip sync or edit_dialogue for Edit Dialogue. Omitted, the project has no default workflow." - changed
Input schema / properties / id / descriptionPrevious value: -"Optional client-supplied project id (UUID) for idempotent creation. Re-sending the same id returns the existing project instead of creating a duplicate; the other request fields are ignored on such a replay. If the id is already used by a different user or organization, or by a deleted project, the request fails with 409."New value: +"Fresh random UUID you generate for this creation; reuse it only when retrying this same creation. Re-sending it returns the existing project and ignores the other fields. An id already used by another user or organization, or by a deleted project, fails with 409." - changed
Input schema / properties / visibility / descriptionPrevious value: -"Who can see the project. Defaults to USER (visible only to the owner)."New value: +"USER (default) keeps the project visible only to you; ORGANIZATION makes it visible to every member of the organization."
- Changed
projects_get1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project ID (UUID)."New value: +"Project id (UUID) from projects_list, projects_create or a tool result that names the project."
- Changed
projects_list3 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results to return. Keep it small and page with cursor."New value: +"Projects per page, 1 to 100; defaults to 10. Keep it small and page with cursor." - changed
Input schema / properties / searchQuery / descriptionPrevious value: -"Text to match against project names."New value: +"Case-insensitive text matched within project names and descriptions. Use only when the user names an existing project, and ask which one when several match instead of taking the first." - changed
Input schema / properties / sortBy / descriptionPrevious value: -"Sort by updatedAt or name."New value: +"updatedAt (default) lists the most recently updated first; name sorts A to Z."
- Changed
projects_list-generations2 fields changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project whose history to read, from projects_list."New value: +"Project whose history to read (UUID), from projects_list or projects_create." - changed
Input schema / properties / status / descriptionPrevious value: -"Filter generations by status"New value: +"Only generations in this status: PENDING, PROCESSING, COMPLETED, FAILED or REJECTED."
- Changed
projects_rename2 fields changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project to rename, from projects_list or projects_create."New value: +"Project to rename (UUID), from projects_list, or from projects_create for the project just made for this request." - changed
Input schema / properties / projectIntent / descriptionPrevious value: -"Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor."New value: +"Set to explicit whenever you pass projectId: the user asked to rename this project, selected it in the interface, or it is the project just created for this request. Never infer it from a matching project name, workflow name or open editor."
- Changed
speech-previews_create4 fields changed- changed
Input schema / properties / idempotencyKey / descriptionPrevious value: -"Persist this request identity before synthesis. Reuse it with the identical script and voice after an uncertain response."New value: +"A fresh UUID, persisted before the call and sent as the Idempotency-Key header. After an uncertain response, reuse it with the identical script and voice; only this key deduplicates, so a new key can bill a second synthesis." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the speech belongs to, from projects_create or projects_list."New value: +"Project the preview is for, from projects_create or projects_list. The tool checks you can access it before synthesizing; pass the same id to speech-previews_get." - changed
Input schema / properties / script / descriptionPrevious value: -"Text to speak, up to 5,000 characters."New value: +"Exact text the user confirmed, spoken as written; up to 5,000 characters." - changed
Input schema / properties / voiceId / descriptionPrevious value: -"An id returned by voices_list. Restricted voices cannot synthesize."New value: +"Voice id returned by voices_list (premade ElevenLabs voices or this organization's clones). A voice with a restriction cannot synthesize; pick another."
- Changed
speech-previews_get1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the speech belongs to, from projects_create or projects_list."New value: +"Project you passed to speech-previews_create, from projects_create or projects_list. It is read first to check access; an id you cannot access returns an error."
- Changed
speech-previews_get-options1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the speech belongs to, from projects_create or projects_list."New value: +"Project the speech preview is for, from projects_create or projects_list. Use the same id for speech-previews_create; an id you cannot access returns an error."
- Changed
transcriptions_analyze-speakers3 fields changed- changed
Input schema / properties / retry / descriptionPrevious value: -"true to run the analysis again for this revision."New value: +"true to start a new attempt after a failed or timed-out one. Omit for a first analysis. Ignored while an analysis is completed or still running." - changed
Input schema / properties / revision / descriptionPrevious value: -"The transcription's revision from transcriptions_get."New value: +"The transcription's revision from transcriptions_get (a 64-character hex string, present once COMPLETED). A stale one fails with 409." - changed
Input schema / properties / sourceVideoUrl / descriptionPrevious value: -"The transcription's sourceVideoUrl from transcriptions_get."New value: +"The transcription's sourceVideoUrl from transcriptions_get, unchanged; any other video is refused with 422."
- Changed
transcriptions_get-speaker-analysis1 field changed- changed
Input schema / properties / wait / descriptionPrevious value: -"Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping."New value: +"Wait on the server while the analysis status is processing, for up to about 50 seconds, then return its latest state; if still processing, call again with wait: true instead of sleeping. Does not wait for an unfinished transcription, which returns 409."
- Changed
transcriptions_slice-speaker-face-track3 fields changed- changed
Input schema / properties / fps / descriptionPrevious value: -"The source video's frame rate."New value: +"Frame rate of the video the timeline lipsyncs, as assets_get-playback-metadata reports it; the face track is resampled by time onto this grid." - changed
Input schema / properties / skip / descriptionPrevious value: -"Optional frame range inside the clip, { startFrame, endFrame }, to leave without boxes."New value: +"Optional range { startFrame, endFrame } (end exclusive) strictly inside the clip that a cut removed from its footage. Those frames are left out of the file, so it keeps one box per remaining frame. Usually omitted." - changed
Input schema / properties / startFrame / descriptionPrevious value: -"First frame of the clip, inclusive."New value: +"First frame of the clip, inclusive, counted from the first frame of the source file: the timeline clip's startFrame."
- Changed
translation-previews_create4 fields changed- changed
Input schema / properties / audioAssetId / descriptionPrevious value: -"Saved AUDIO asset to translate, such as an audio-trims_create result."New value: +"Saved AUDIO asset to translate, such as one from assets_create (type=AUDIO), assets_list or audio-trims_create; the same asset you quoted with translation-previews_estimate." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the translation belongs to, from projects_create or projects_list."New value: +"Project for the job: one just created with projects_create for this request, or one the user explicitly selected; pass projectIntent=explicit with it. Use the same id for translation-previews_get." - changed
Input schema / properties / sourceLang / descriptionPrevious value: -"Optional; the source language is detected."New value: +"Optional and usually omitted: the source language is detected (sent as auto)." - changed
Input schema / properties / targetLang / descriptionPrevious value: -"Target language code from dubbing_get-options."New value: +"Language code to translate into, from dubbing_get-options targetLanguages (for example es or pt-BR)."
- Changed
translation-previews_estimate1 field changed- changed
Input schema / properties / audioAssetId / descriptionPrevious value: -"Saved AUDIO asset to translate, such as an audio-trims_create result."New value: +"Saved AUDIO asset to quote, such as one from assets_create (type=AUDIO), assets_list or audio-trims_create; the same asset translation-previews_create will translate."
- Changed
translation-previews_get1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Project the translation belongs to, from projects_create or projects_list."New value: +"The projectId passed to translation-previews_create for this job."
- Changed
voices_list1 field changed- changed
Input schema / properties / provider / descriptionPrevious value: -"Only voices from this provider. Only elevenlabs is supported."New value: +"Return only voices from this provider. Only elevenlabs is accepted; omit to list every voice."
39 tool updates
- Changed
assets_count7 fields changed- added
Input schema / properties / cursor / descriptionAdded value: +"Ignored when counting." - added
Input schema / properties / limit / descriptionAdded value: +"Ignored when counting." - added
Input schema / properties / projectId / descriptionAdded value: +"Only assets attached to this project (an id from projects_list or projects_create)." - added
Input schema / properties / searchQuery / descriptionAdded value: +"Text to match against names." - added
Input schema / properties / sortBy / descriptionAdded value: +"Sort order, such as dateDesc for newest first." - added
Input schema / properties / types / descriptionAdded value: +"Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list." - added
Input schema / properties / userId / descriptionAdded value: +"Only assets created by this user id."
- Changed
assets_create13 fields changed- added
Input schema / properties / contentSha256 / descriptionAdded value: +"Optional SHA-256 hex digest of the file." - added
Input schema / properties / durationSeconds / descriptionAdded value: +"Media length in seconds, when known." - added
Input schema / properties / format / descriptionAdded value: +"File format or extension, such as mp4 or wav, when known." - added
Input schema / properties / height / descriptionAdded value: +"Video or image height in pixels, when known." - added
Input schema / properties / inputType / descriptionAdded value: +"How the media was produced, such as UPLOAD or URL. Usually omitted." - added
Input schema / properties / name / descriptionAdded value: +"Display name for the asset." - added
Input schema / properties / projectId / descriptionAdded value: +"Project to attach the asset to, from projects_create or projects_list." - added
Input schema / properties / size / descriptionAdded value: +"File size in bytes, when known." - added
Input schema / properties / thumbnailUrl / descriptionAdded value: +"Optional preview image URL for the asset." - added
Input schema / properties / type / descriptionAdded value: +"Media type: VIDEO, AUDIO or IMAGE." - added
Input schema / properties / url / descriptionAdded value: +"Media URL: the url assets_create-upload-url returned, a public https:// file, or a YouTube, TikTok, Instagram or Facebook video link." - added
Input schema / properties / visibility / descriptionAdded value: +"USER keeps it private to you; ORGANIZATION shares it with your team." - added
Input schema / properties / width / descriptionAdded value: +"Video or image width in pixels, when known."
- Changed
assets_create-upload-url3 fields changed- added
Input schema / properties / contentType / descriptionAdded value: +"MIME type of the file, such as video/mp4; send the same value when you PUT it." - added
Input schema / properties / fileName / descriptionAdded value: +"Name of the local file, with its extension." - added
Input schema / properties / size / descriptionAdded value: +"File size in bytes."
- Changed
assets_get1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Asset ID"New value: +"Asset id from assets_list."
- Changed
assets_get-download-url1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Asset ID"New value: +"Asset id from assets_list."
- Changed
assets_get-playback-metadata1 field changed- added
Input schema / properties / assetId / descriptionAdded value: +"Asset id from assets_list."
- Changed
assets_list7 fields changed- added
Input schema / properties / cursor / descriptionAdded value: +"The previous page's nextCursor, to read the next page. Omit for the first page." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of results to return. Keep it small and page with cursor." - added
Input schema / properties / projectId / descriptionAdded value: +"Only assets attached to this project (an id from projects_list or projects_create)." - added
Input schema / properties / searchQuery / descriptionAdded value: +"Text to match against names." - added
Input schema / properties / sortBy / descriptionAdded value: +"Sort order, such as dateDesc for newest first." - added
Input schema / properties / types / descriptionAdded value: +"Only these media types: VIDEO, AUDIO or IMAGE, as one value or a list." - added
Input schema / properties / userId / descriptionAdded value: +"Only assets created by this user id."
- Changed
assets_update8 fields changed- added
Input schema / properties / durationSeconds / descriptionAdded value: +"Media length in seconds, when known." - added
Input schema / properties / format / descriptionAdded value: +"File format or extension, such as mp4 or wav, when known." - added
Input schema / properties / height / descriptionAdded value: +"Video or image height in pixels, when known." - changed
Input schema / properties / id / descriptionPrevious value: -"Asset ID"New value: +"Asset id from assets_list." - added
Input schema / properties / name / descriptionAdded value: +"New display name." - added
Input schema / properties / size / descriptionAdded value: +"File size in bytes, when known." - added
Input schema / properties / visibility / descriptionAdded value: +"USER keeps it private to you; ORGANIZATION shares it with your team." - added
Input schema / properties / width / descriptionAdded value: +"Video or image width in pixels, when known."
- Changed
audio-trims_create3 fields changed- added
Input schema / properties / durationSeconds / descriptionAdded value: +"Seconds to keep from the start of the audio, up to 3600." - added
Input schema / properties / idempotencyKey / descriptionAdded value: +"A new UUID saved before the call. Reuse it with identical input only to recover an uncertain response." - added
Input schema / properties / projectId / descriptionAdded value: +"Project to save the shortened audio in, from projects_create or projects_list."
- Changed
audio-trims_get1 field changed- added
Input schema / properties / id / descriptionAdded value: +"Audio trim id from audio-trims_create."
- Changed
batches_list1 field changed- added
Input schema / properties / status / descriptionAdded value: +"Only batches in this status, such as PROCESSING for batches still running."
- Changed
dialogue_upload-source2 fields changed- added
Input schema / properties / projectId / descriptionAdded value: +"Project the Edit Dialogue work belongs to, from projects_create." - added
Input schema / properties / videoAssetId / descriptionAdded value: +"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."
- Changed
dialogue-previews_get3 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Preview id from dialogue-previews_create." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the Edit Dialogue work belongs to, from projects_create." - added
Input schema / properties / videoAssetId / descriptionAdded value: +"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."
- Changed
dialogue-transcriptions_create2 fields changed- added
Input schema / properties / projectId / descriptionAdded value: +"Project the Edit Dialogue work belongs to, from projects_create." - added
Input schema / properties / videoAssetId / descriptionAdded value: +"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."
- Changed
dialogue-transcriptions_get3 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Transcription id from dialogue-transcriptions_create." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the Edit Dialogue work belongs to, from projects_create." - added
Input schema / properties / videoAssetId / descriptionAdded value: +"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."
- Changed
dialogue-videos_create9 fields changed- added
Input schema / properties / continuation / properties / parentGenerationId / descriptionAdded value: +"Id of the existing generation this continues." - added
Input schema / properties / continuation / properties / workflow / descriptionAdded value: +"The parent generation's workflow, from generations_get-continuation." - added
Input schema / properties / options / descriptionAdded value: +"Optional model controls. Omit any field to use its default." - changed
Input schema / properties / options / properties / active_speaker_detection / anyOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "description": "Zero-based video frame that coordinates refer to.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } +] - added
Input schema / properties / options / properties / active_speaker_detection / descriptionAdded value: +"Which face to lipsync when several people are visible: true or { auto_detect: true } to find the speaker, or frame_number plus coordinates to pick one. Omit for a single face or an image." - added
Input schema / properties / options / properties / model_mode / descriptionAdded value: +"How much of the face the model may change: lips, face or head." - added
Input schema / properties / options / properties / occlusion_detection_enabled / descriptionAdded value: +"Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower." - added
Input schema / properties / options / properties / sync_mode / descriptionAdded value: +"How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio)." - added
Input schema / properties / options / properties / temperature / descriptionAdded value: +"How expressive the mouth movement is, from 0 to 1. Omit for the model default."
- Changed
dialogue-videos_estimate11 fields changed- added
Input schema / properties / dialogueEditId / descriptionAdded value: +"Id of the completed, user-approved preview from dialogue-previews_create." - added
Input schema / properties / model / descriptionAdded value: +"Lipsync model name from models_list, such as sync-3." - added
Input schema / properties / options / descriptionAdded value: +"Optional model controls. Omit any field to use its default." - changed
Input schema / properties / options / properties / active_speaker_detection / anyOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "description": "Zero-based video frame that coordinates refer to.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } +] - added
Input schema / properties / options / properties / active_speaker_detection / descriptionAdded value: +"Which face to lipsync when several people are visible: true or { auto_detect: true } to find the speaker, or frame_number plus coordinates to pick one. Omit for a single face or an image." - added
Input schema / properties / options / properties / model_mode / descriptionAdded value: +"How much of the face the model may change: lips, face or head." - added
Input schema / properties / options / properties / occlusion_detection_enabled / descriptionAdded value: +"Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower." - added
Input schema / properties / options / properties / sync_mode / descriptionAdded value: +"How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio)." - added
Input schema / properties / options / properties / temperature / descriptionAdded value: +"How expressive the mouth movement is, from 0 to 1. Omit for the model default." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the Edit Dialogue work belongs to, from projects_create." - added
Input schema / properties / videoAssetId / descriptionAdded value: +"Saved VIDEO asset being edited. Use the videoAssetId dialogue-transcriptions_create returned when it made a copy."
- Changed
dubbing_create11 fields changed- added
Input schema / properties / continuation / descriptionAdded value: +"Only when the user explicitly continues an existing generation in this project: the parent generation and its workflow." - added
Input schema / properties / continuation / properties / parentGenerationId / descriptionAdded value: +"Id of the existing generation this continues." - added
Input schema / properties / continuation / properties / workflow / descriptionAdded value: +"The parent generation's workflow, from generations_get-continuation." - added
Input schema / properties / options / descriptionAdded value: +"Optional model controls. Omit any field to use its default." - changed
Input schema / properties / options / properties / active_speaker_detection / anyOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "description": "Zero-based video frame that coordinates refer to.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } +] - added
Input schema / properties / options / properties / active_speaker_detection / descriptionAdded value: +"Which face to lipsync when several people are visible: true or { auto_detect: true } to find the speaker, or frame_number plus coordinates to pick one. Omit for a single face or an image." - added
Input schema / properties / options / properties / model_mode / descriptionAdded value: +"How much of the face the model may change: lips, face or head." - added
Input schema / properties / options / properties / occlusion_detection_enabled / descriptionAdded value: +"Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower." - added
Input schema / properties / options / properties / sync_mode / descriptionAdded value: +"How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio)." - added
Input schema / properties / options / properties / temperature / descriptionAdded value: +"How expressive the mouth movement is, from 0 to 1. Omit for the model default." - added
Input schema / properties / sourceLang / descriptionAdded value: +"Spoken language of the source video. Leave as auto to detect it."
- Changed
generations_estimate-cost2 fields changed- added
Input schema / properties / model / descriptionAdded value: +"Model name from models_list, such as sync-3." - added
Input schema / properties / reasoningEnabled / descriptionAdded value: +"Quote with reasoning on. Only lipsync-2-pro supports it."
- Changed
generations_get1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Job ID"New value: +"Generation id returned by a create tool or generations_list."
- Changed
generations_get-continuation3 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Id of the existing generation to continue from." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the generation belongs to." - changed
Output schema / anyOfPrevious value: -[ - { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, - "properties": { - "generation": { - "additionalProperties": false, - "properties": { - "dialogueEditJobId": { - "anyOf": [ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "type": "null" - } - ] - }, - "id": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "inputs": { - "items": { - "additionalProperties": false, - "properties": { - "assetId": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "generatedBy": { - "const": "tts", - "type": "string" - }, - "provider": { - "additionalProperties": false, - "properties": { - "name": { - "type": "string" - }, - "script": { - "type": "string" - }, - "similarityBoost": { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - "stability": { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - "voiceId": { - "type": "string" - } - }, - "required": [ - "name", - "script", - "voiceId" - ], - "type": "object" - }, - "refId": { - "type": "string" - }, - "segments_frames": { - "items": { - "items": { - "type": "number" - }, - "type": "array" - }, - "type": "array" - }, - "segments_secs": { - "items": { - "items": { - "type": "number" - }, - "type": "array" - }, - "type": "array" - }, - "trim_secs": { - "items": { - "type": "number" - }, - "type": "array" - }, - "type": { - "enum": [ - "video", - "image", - "audio", - "text" - ], - "type": "string" - }, - "url": { - "format": "uri", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - "type": "array" - }, - "modelName": { - "minLength": 1, - "type": "string" - }, - "options": { - "additionalProperties": false, - "properties": { - "active_speaker_detection": { - "anyOf": [ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "bounding_boxes": { - "items": { - "anyOf": [ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "type": "array" - }, - "bounding_boxes_url": { - "format": "uri", - "type": "string" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "type": "number" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } - ] - }, - "model_mode": { - "type": "string" - }, - "occlusion_detection_enabled": { - "type": "boolean" - }, - "reasoning_enabled": { - "description": "Only lipsync-2-pro supports reasoning; it is ignored for other models.", - "type": "boolean" - }, - "sync_mode": { - "enum": [ - "bounce", - "loop", - "cut_off", - "silence", - "remap" - ], - "type": "string" - }, - "temperature": { - "anyOf": [ - { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "type": "object" - }, - "outputMediaUrl": { - "anyOf": [ - { - "format": "uri", - "type": "string" - }, - { - "type": "null" - } - ] - }, - "parentGenerationId": { - "anyOf": [ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "type": "null" - } - ] - }, - "projectId": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "renderedFromAssetId": { - "anyOf": [ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "type": "null" - } - ] - }, - "segments": { - "anyOf": [ - { - "items": { - "additionalProperties": false, - "properties": { - "audioInput": { - "additionalProperties": false, - "properties": { - "endTime": { - "type": "number" - }, - "refId": { - "type": "string" - }, - "startTime": { - "type": "number" - } - }, - "required": [ - "refId" - ], - "type": "object" - }, - "endFrame": { - "type": "number" - }, - "endTime": { - "type": "number" - }, - "optionsOverride": { - "additionalProperties": false, - "properties": { - "active_speaker_detection": { - "anyOf": [ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "bounding_boxes": { - "items": { - "anyOf": [ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "type": "array" - }, - "bounding_boxes_url": { - "format": "uri", - "type": "string" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "type": "number" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } - ] - }, - "model_mode": { - "type": "string" - }, - "occlusion_detection_enabled": { - "type": "boolean" - }, - "reasoning_enabled": { - "description": "Only lipsync-2-pro supports reasoning; it is ignored for other models.", - "type": "boolean" - }, - "sync_mode": { - "enum": [ - "bounce", - "loop", - "cut_off", - "silence", - "remap" - ], - "type": "string" - }, - "temperature": { - "anyOf": [ - { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "type": "object" - }, - "startFrame": { - "type": "number" - }, - "startTime": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "speakers": { - "anyOf": [ - { - "items": { - "additionalProperties": false, - "properties": { - "audio": { - "additionalProperties": false, - "properties": { - "endTime": { - "type": "number" - }, - "refId": { - "type": "string" - }, - "startTime": { - "type": "number" - } - }, - "required": [ - "refId" - ], - "type": "object" - }, - "face": { - "additionalProperties": false, - "properties": { - "bounding_boxes": { - "items": { - "anyOf": [ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "type": "array" - }, - "bounding_boxes_url": { - "format": "uri", - "type": "string" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "type": "number" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - }, - "id": { - "type": "string" - } - }, - "required": [ - "id", - "audio", - "face" - ], - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "status": { - "enum": [ - "PENDING", - "PROCESSING", - "COMPLETED", - "FAILED", - "REJECTED" - ], - "type": "string" - }, - "workflow": { - "anyOf": [ - { - "enum": [ - "lipsync", - "translate_and_dub", - "image_to_video", - "edit_dialogue", - "change_appearance", - "timeline", - "assistant" - ], - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "id", - "projectId", - "status", - "modelName", - "options", - "inputs" - ], - "type": "object" - }, - "submissionContextVersion": { - "const": 1, - "type": "number" - } - }, - "required": [ - "submissionContextVersion", - "generation" - ], - "type": "object" - }, - { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, - "properties": { - "error": { - "additionalProperties": false, - "properties": { - "code": { - "type": "string" - }, - "generationId": { - "type": "string" - }, - "importJobId": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "importStatus": { - "enum": [ - "queued", - "downloading", - "processing", - "completed", - "failed" - ], - "type": "string" - }, - "message": { - "type": "string" - }, - "progress": { - "maximum": 100, - "minimum": 0, - "type": "number" - }, - "retryAfterMs": { - "type": "number" - }, - "retryable": { - "type": "boolean" - }, - "status": { - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - } - }, - "required": [ - "message" - ], - "type": "object" - } - }, - "required": [ - "error" - ], - "type": "object" - } -]New value: +[ + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "generation": { + "additionalProperties": false, + "properties": { + "dialogueEditJobId": { + "anyOf": [ + { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "id": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "inputs": { + "items": { + "additionalProperties": false, + "properties": { + "assetId": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "generatedBy": { + "const": "tts", + "type": "string" + }, + "provider": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "script": { + "type": "string" + }, + "similarityBoost": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "stability": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "voiceId": { + "type": "string" + } + }, + "required": [ + "name", + "script", + "voiceId" + ], + "type": "object" + }, + "refId": { + "type": "string" + }, + "segments_frames": { + "items": { + "items": { + "type": "number" + }, + "type": "array" + }, + "type": "array" + }, + "segments_secs": { + "items": { + "items": { + "type": "number" + }, + "type": "array" + }, + "type": "array" + }, + "trim_secs": { + "items": { + "type": "number" + }, + "type": "array" + }, + "type": { + "enum": [ + "video", + "image", + "audio", + "text" + ], + "type": "string" + }, + "url": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "type": "array" + }, + "modelName": { + "minLength": 1, + "type": "string" + }, + "options": { + "additionalProperties": false, + "properties": { + "active_speaker_detection": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "bounding_boxes": { + "items": { + "anyOf": [ + { + "items": { + "type": "number" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "type": "array" + }, + "bounding_boxes_url": { + "format": "uri", + "type": "string" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "type": "number" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } + ] + }, + "model_mode": { + "type": "string" + }, + "occlusion_detection_enabled": { + "description": "Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower.", + "type": "boolean" + }, + "reasoning_enabled": { + "description": "Only lipsync-2-pro supports reasoning; it is ignored for other models.", + "type": "boolean" + }, + "sync_mode": { + "description": "How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio).", + "enum": [ + "bounce", + "loop", + "cut_off", + "silence", + "remap" + ], + "type": "string" + }, + "temperature": { + "anyOf": [ + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "description": "How expressive the mouth movement is, from 0 to 1. Omit for the model default." + } + }, + "type": "object" + }, + "outputMediaUrl": { + "anyOf": [ + { + "format": "uri", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "parentGenerationId": { + "anyOf": [ + { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "projectId": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "renderedFromAssetId": { + "anyOf": [ + { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + { + "type": "null" + } + ] + }, + "segments": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "audioInput": { + "additionalProperties": false, + "properties": { + "endTime": { + "type": "number" + }, + "refId": { + "type": "string" + }, + "startTime": { + "type": "number" + } + }, + "required": [ + "refId" + ], + "type": "object" + }, + "endFrame": { + "type": "number" + }, + "endTime": { + "type": "number" + }, + "optionsOverride": { + "additionalProperties": false, + "properties": { + "active_speaker_detection": { + "anyOf": [ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "bounding_boxes": { + "items": { + "anyOf": [ + { + "items": { + "type": "number" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "type": "array" + }, + "bounding_boxes_url": { + "format": "uri", + "type": "string" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "type": "number" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } + ] + }, + "model_mode": { + "type": "string" + }, + "occlusion_detection_enabled": { + "description": "Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower.", + "type": "boolean" + }, + "reasoning_enabled": { + "description": "Only lipsync-2-pro supports reasoning; it is ignored for other models.", + "type": "boolean" + }, + "sync_mode": { + "description": "How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio).", + "enum": [ + "bounce", + "loop", + "cut_off", + "silence", + "remap" + ], + "type": "string" + }, + "temperature": { + "anyOf": [ + { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "description": "How expressive the mouth movement is, from 0 to 1. Omit for the model default." + } + }, + "type": "object" + }, + "startFrame": { + "type": "number" + }, + "startTime": { + "type": "number" + } + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "speakers": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "audio": { + "additionalProperties": false, + "properties": { + "endTime": { + "type": "number" + }, + "refId": { + "type": "string" + }, + "startTime": { + "type": "number" + } + }, + "required": [ + "refId" + ], + "type": "object" + }, + "face": { + "additionalProperties": false, + "properties": { + "bounding_boxes": { + "items": { + "anyOf": [ + { + "items": { + "type": "number" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "type": "array" + }, + "bounding_boxes_url": { + "format": "uri", + "type": "string" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "type": "number" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id", + "audio", + "face" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "status": { + "enum": [ + "PENDING", + "PROCESSING", + "COMPLETED", + "FAILED", + "REJECTED" + ], + "type": "string" + }, + "workflow": { + "anyOf": [ + { + "enum": [ + "lipsync", + "translate_and_dub", + "image_to_video", + "edit_dialogue", + "change_appearance", + "timeline", + "assistant" + ], + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "id", + "projectId", + "status", + "modelName", + "options", + "inputs" + ], + "type": "object" + }, + "submissionContextVersion": { + "const": 1, + "type": "number" + } + }, + "required": [ + "submissionContextVersion", + "generation" + ], + "type": "object" + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "generationId": { + "type": "string" + }, + "importJobId": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "importStatus": { + "enum": [ + "queued", + "downloading", + "processing", + "completed", + "failed" + ], + "type": "string" + }, + "message": { + "type": "string" + }, + "progress": { + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "retryAfterMs": { + "type": "number" + }, + "retryable": { + "type": "boolean" + }, + "status": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "message" + ], + "type": "object" + } + }, + "required": [ + "error" + ], + "type": "object" + } +]
- Changed
generations_list1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Filter to a live project accessible to the session user or API-key owner. Inaccessible projects return an empty list."New value: +"Only generations in this project, from projects_list or projects_create."
- Changed
lipsync_create9 fields changed- added
Input schema / properties / continuation / descriptionAdded value: +"Only when the user explicitly continues an existing generation in this project: the parent generation and its workflow." - added
Input schema / properties / continuation / properties / parentGenerationId / descriptionAdded value: +"Id of the existing generation this continues." - added
Input schema / properties / continuation / properties / workflow / descriptionAdded value: +"The parent generation's workflow, from generations_get-continuation." - changed
Input schema / properties / options / properties / active_speaker_detection / anyOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "description": "Zero-based video frame that coordinates refer to.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } +] - added
Input schema / properties / options / properties / active_speaker_detection / descriptionAdded value: +"Which face to lipsync when several people are visible: true or { auto_detect: true } to find the speaker, or frame_number plus coordinates to pick one. Omit for a single face or an image." - added
Input schema / properties / options / properties / model_mode / descriptionAdded value: +"How much of the face the model may change: lips, face or head." - added
Input schema / properties / options / properties / occlusion_detection_enabled / descriptionAdded value: +"Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower." - added
Input schema / properties / options / properties / sync_mode / descriptionAdded value: +"How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio)." - added
Input schema / properties / options / properties / temperature / descriptionAdded value: +"How expressive the mouth movement is, from 0 to 1. Omit for the model default."
- Changed
lipsync_create-timeline7 fields changed- added
Input schema / properties / options / descriptionAdded value: +"Optional model controls. Omit any field to use its default." - changed
Input schema / properties / options / properties / active_speaker_detection / anyOfPrevious value: -[ - { - "type": "boolean" - }, - { - "additionalProperties": false, - "properties": { - "auto_detect": { - "type": "boolean" - }, - "coordinates": { - "items": false, - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "face_image": { - "type": "string" - }, - "frame_number": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "use_v2": { - "type": "boolean" - }, - "v3": { - "type": "boolean" - } - }, - "type": "object" - } -]New value: +[ + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "auto_detect": { + "description": "Find the person speaking automatically.", + "type": "boolean" + }, + "coordinates": { + "description": "[x, y] pixel position of the speaker's face on frame_number.", + "items": false, + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "face_image": { + "description": "URL of a reference image of the speaker's face.", + "type": "string" + }, + "frame_number": { + "description": "Zero-based video frame that coordinates refer to.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "use_v2": { + "description": "Use the second-generation speaker detector.", + "type": "boolean" + }, + "v3": { + "description": "Use the third-generation speaker detector.", + "type": "boolean" + } + }, + "type": "object" + } +] - added
Input schema / properties / options / properties / active_speaker_detection / descriptionAdded value: +"Which face to lipsync when several people are visible: true or { auto_detect: true } to find the speaker, or frame_number plus coordinates to pick one. Omit for a single face or an image." - added
Input schema / properties / options / properties / model_mode / descriptionAdded value: +"How much of the face the model may change: lips, face or head." - added
Input schema / properties / options / properties / occlusion_detection_enabled / descriptionAdded value: +"Keep hands, microphones and other objects that pass in front of the mouth in front of it. Slower." - added
Input schema / properties / options / properties / sync_mode / descriptionAdded value: +"How to fit audio and video of different lengths: bounce (play the video forward, then in reverse), loop, cut_off (stop at the shorter input), silence (pad with silence to the longer input) or remap (change the video speed to match the audio)." - added
Input schema / properties / options / properties / temperature / descriptionAdded value: +"How expressive the mouth movement is, from 0 to 1. Omit for the model default."
- Changed
projects_create2 fields changed- added
Input schema / properties / description / descriptionAdded value: +"Optional project notes." - added
Input schema / properties / name / descriptionAdded value: +"Project name shown in Studio."
- Changed
projects_list4 fields changed- added
Input schema / properties / cursor / descriptionAdded value: +"The previous page's nextCursor, to read the next page. Omit for the first page." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of results to return. Keep it small and page with cursor." - added
Input schema / properties / searchQuery / descriptionAdded value: +"Text to match against project names." - added
Input schema / properties / sortBy / descriptionAdded value: +"Sort by updatedAt or name."
- Changed
projects_list-generations1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"Filter to a live project accessible to the session user or API-key owner. Inaccessible projects return an empty list."New value: +"Project whose history to read, from projects_list."
- Changed
projects_rename2 fields changed- added
Input schema / properties / name / descriptionAdded value: +"New project name, up to 255 characters." - added
Input schema / properties / projectId / descriptionAdded value: +"Project to rename, from projects_list or projects_create."
- Changed
speech-previews_create4 fields changed- added
Input schema / properties / projectId / descriptionAdded value: +"Project the speech belongs to, from projects_create or projects_list." - added
Input schema / properties / script / descriptionAdded value: +"Text to speak, up to 5,000 characters." - added
Input schema / properties / similarityBoost / descriptionAdded value: +"How closely to match the selected voice, from 0 to 1." - added
Input schema / properties / stability / descriptionAdded value: +"Voice consistency from 0 to 1; higher is steadier, lower is more expressive."
- Changed
speech-previews_get2 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Speech preview id from speech-previews_create." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the speech belongs to, from projects_create or projects_list."
- Changed
speech-previews_get-options1 field changed- added
Input schema / properties / projectId / descriptionAdded value: +"Project the speech belongs to, from projects_create or projects_list."
- Changed
transcriptions_analyze-speakers4 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Transcription id from transcriptions_create." - added
Input schema / properties / retry / descriptionAdded value: +"true to run the analysis again for this revision." - added
Input schema / properties / revision / descriptionAdded value: +"The transcription's revision from transcriptions_get." - added
Input schema / properties / sourceVideoUrl / descriptionAdded value: +"The transcription's sourceVideoUrl from transcriptions_get."
- Changed
transcriptions_get1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Transcription job id"New value: +"Transcription id from transcriptions_create."
- Changed
transcriptions_get-speaker-analysis1 field changed- added
Input schema / properties / id / descriptionAdded value: +"Transcription id from transcriptions_create."
- Changed
transcriptions_slice-speaker-face-track7 fields changed- added
Input schema / properties / endFrame / descriptionAdded value: +"Frame after the clip ends (exclusive): the timeline clip endFrame + 1." - added
Input schema / properties / fps / descriptionAdded value: +"The source video's frame rate." - added
Input schema / properties / id / descriptionAdded value: +"Transcription id from transcriptions_create." - added
Input schema / properties / revision / descriptionAdded value: +"The revision returned by transcriptions_get-speaker-analysis, so the call matches that analysis." - added
Input schema / properties / skip / descriptionAdded value: +"Optional frame range inside the clip, { startFrame, endFrame }, to leave without boxes." - added
Input schema / properties / speakerId / descriptionAdded value: +"A matched speaker id from transcriptions_get-speaker-analysis." - added
Input schema / properties / startFrame / descriptionAdded value: +"First frame of the clip, inclusive."
- Changed
translation-previews_create4 fields changed- added
Input schema / properties / audioAssetId / descriptionAdded value: +"Saved AUDIO asset to translate, such as an audio-trims_create result." - added
Input schema / properties / idempotencyKey / descriptionAdded value: +"A new UUID saved before the call. Reuse it with identical input only to recover an uncertain response." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the translation belongs to, from projects_create or projects_list." - added
Input schema / properties / targetLang / descriptionAdded value: +"Target language code from dubbing_get-options."
- Changed
translation-previews_estimate2 fields changed- added
Input schema / properties / audioAssetId / descriptionAdded value: +"Saved AUDIO asset to translate, such as an audio-trims_create result." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the translation belongs to, from projects_create or projects_list."
- Changed
translation-previews_get2 fields changed- added
Input schema / properties / id / descriptionAdded value: +"Translation preview id from translation-previews_create." - added
Input schema / properties / projectId / descriptionAdded value: +"Project the translation belongs to, from projects_create or projects_list."
- Changed
voices_list1 field changed- added
Input schema / properties / provider / descriptionAdded value: +"Only voices from this provider. Only elevenlabs is supported."
77 tool updates
v0.1.5- Added
account_get-context - Added
account_get-usage - Added
assets_count - Changed
assets_create7 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / contentSha256Added value: +{ + "type": "string" +} - changed
Input schema / properties / inputType / enumPrevious value: -[ - "UPLOAD", - "URL", - "RECORD", - "TTS", - "EXTRACT", - "DUB", - "DUB_SOURCE", - "PLATFORM_IMPORT", - "PLUGIN_PREMIERE_FILE", - "PLUGIN_PREMIERE_TIMELINE_SELECTION", - "PLUGIN_RESOLVE_FILE", - "PLUGIN_RESOLVE_TIMELINE_SELECTION" -]New value: +[ + "UPLOAD", + "URL", + "RECORD", + "TTS", + "EXTRACT", + "DUB", + "DUB_SOURCE", + "PLATFORM_IMPORT", + "DIALOGUE_EDIT", + "PLUGIN_PREMIERE_FILE", + "PLUGIN_PREMIERE_TIMELINE_SELECTION", + "PLUGIN_RESOLVE_FILE", + "PLUGIN_RESOLVE_TIMELINE_SELECTION" +] - added
Input schema / properties / projectIntentAdded value: +{ + "const": "explicit", + "description": "Required with projectId. Set only for an explicit user project selection/update, or the new project just created for this request. Never infer intent from a matching project name, workflow name or active editor.", + "type": "string" +} - removed
Input schema / properties / thumbnailUrl / typeRemoved value: -"string" - added
Input schema / properties / waitAdded value: +{ + "description": "Wait on the server until the job finishes or about 50 seconds pass, then return its latest state. If it is still running, call again with wait: true instead of sleeping.", + "type": "boolean" +}
- Changed
assets_create-upload-url2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
assets_delete - Changed
assets_get2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
assets_get-all - Added
assets_get-download-url - Added
assets_get-playback-metadata - Added
assets_list - Changed
assets_update2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false
- Added
audio-trims_create - Added
audio-trims_get - Added
batches_create - Added
batches_get - Added
batches_list - Removed
create-lipsync - Added
dialogue_get-options - Added
dialogue_upload-source - Added
dialogue-previews_create - Added
dialogue-previews_get - Added
dialogue-transcriptions_create - Added
dialogue-transcriptions_get - Added
dialogue-videos_create - Added
dialogue-videos_estimate - Added
dubbing_create - Added
dubbing_get-options - Added
feedback_send - Removed
generate_create-generation - Removed
generate_estimate-cost - Removed
generate_get-generation - Removed
generate_get-generations - Removed
generations_delete - Changed
generations_estimate-cost12 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / audioDurationAdded value: +{ + "description": "Measured replacement audio duration in seconds. Prefer this over a script estimate once speech audio exists.", + "exclusiveMinimum": 0, + "type": "number" +} - added
Input schema / properties / duration / descriptionAdded value: +"Billable output seconds, or source seconds for translate-and-dub. For replacement speech, supply script or measured audioDuration instead. Never use the source video length for a shorter replacement script." - added
Input schema / properties / fps / descriptionAdded value: +"Source video frame rate. When omitted, credit-billed organizations are quoted at 25, the rate generation admission holds credits at when the source frame rate cannot be read; other organizations at 30." - added
Input schema / properties / organizationIdAdded value: +{ + "description": "Run only this call in another of the user’s Sync organizations, by id from organizations_list, when the user asks for it (for example “generate this in the Acme org”). The session keeps its organization; reads of the ids this call returns stay in this organization. Omit to use the session’s organization.", + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" +} - added
Input schema / properties / scriptAdded value: +{ + "description": "Replacement speech text. Estimates spoken duration without synthesizing audio. Use for script-driven lipsync instead of pricing the full source video. An approximate quote; final speech length may differ.", + "maxLength": 5000, + "minLength": 1, + "type": "string" +} - added
Input schema / properties / syncModeAdded value: +{ + "description": "The same sync_mode selected for generation. For videos, cut_off uses the shorter input and silence the longer input. Images and other modes follow replacement audio duration.", + "enum": [ + "bounce", + "loop", + "cut_off", + "silence", + "remap" + ], + "type": "string" +} - added
Input schema / properties / videoDurationAdded value: +{ + "description": "Source video duration in seconds, used with syncMode to account for cut_off or silence. Omit for an image.", + "exclusiveMinimum": 0, + "type": "number" +} - added
Input schema / properties / visualTypeAdded value: +{ + "description": "Visual input type. Set image for image-to-video quotes; images always follow speech duration, including with cut_off or silence. Videos require videoDuration for those modes.", + "enum": [ + "image", + "video" + ], + "type": "string" +} - added
Input schema / properties / workflowAdded value: +{ + "description": "Omit for lip-sync only. translate-and-dub includes dubbing and lip-sync, estimated using the source duration. Actual output duration may differ.", + "enum": [ + "lipsync", + "translate-and-dub" + ], + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "model", - "duration" -]New value: +[ + "model" +]
- Added
generations_get - Removed
generations_get-by-id - Added
generations_get-continuation - Added
generations_get-costs - Added
generations_list - Added
jobs_get - Added
jobs_wait - Added
lipsync_create - Added
lipsync_create-timeline - Removed
models_get - Added
models_list - Removed
open-upload-widget - Added
organizations_list - Added
organizations_select - Removed
projects_attach-asset - Changed
projects_create2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
projects_delete - Removed
projects_detach-asset - Changed
projects_get5 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / id / descriptionPrevious value: -"Project ID (UUID)"New value: +"Deprecated alias of projectId." - added
Input schema / properties / projectIdAdded value: +{ + "description": "Project ID (UUID).", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "id" -]
- Removed
projects_get-all - Added
projects_list - Added
projects_list-generations - Added
projects_rename - Removed
projects_update - Added
speech-previews_create - Added
speech-previews_get - Added
speech-previews_get-options - Added
transcriptions_analyze-speakers - Added
transcriptions_create - Added
transcriptions_get - Added
transcriptions_get-speaker-analysis - Added
transcriptions_slice-speaker-face-track - Added
translation-previews_create - Added
translation-previews_estimate - Added
translation-previews_get - Removed
tts_create - Removed
upload-media - Removed
voices_clone-voice - Removed
voices_delete-voice - Removed
voices_get-voice - Removed
voices_get-voices - Added
voices_list
29 tool updates
v0.1.4- First observed
assets_create - First observed
assets_create-upload-url - First observed
assets_delete - First observed
assets_get - First observed
assets_get-all - First observed
assets_update - First observed
create-lipsync - First observed
generate_create-generation - First observed
generate_estimate-cost - First observed
generate_get-generation - First observed
generate_get-generations - First observed
generations_delete - First observed
generations_estimate-cost - First observed
generations_get-by-id - First observed
models_get - First observed
open-upload-widget - First observed
projects_attach-asset - First observed
projects_create - First observed
projects_delete - First observed
projects_detach-asset - First observed
projects_get - First observed
projects_get-all - First observed
projects_update - First observed
tts_create - First observed
upload-media - First observed
voices_clone-voice - First observed
voices_delete-voice - First observed
voices_get-voice - First observed
voices_get-voices
TDQS
Scored across 57 tools
Most workflow-specific create tools are clearly distinguished, but the surface has multiple overlapping read/polling paths: generations_get, jobs_get, jobs_wait, jobs_get-many, batches_get, and several preview-specific get tools all track asynchronous work. The lengthy descriptions explicitly cross-reference alternatives, but an agent must read carefully to choose correctly among 57 tools.
Names generally follow a domain_action pattern, but conventions are mixed: some domains use underscores (assets_create, projects_get) while others use hyphens (translation-previews_create, dialogue-videos_create, speech-previews_get-options). Qualifiers append with hyphens (lipsync_create-timeline, generations_estimate-cost), which is readable but not fully consistent.
At 57 tools, the surface is far beyond a well-scoped set and imposes heavy selection burden. The platform is broad, but many operations are split into highly granular create/get/estimate/preview/job variants, making the overall tool count excessive for practical agent use.
Coverage is unusually broad: assets, projects, generations, jobs, batches, transcriptions, speaker analysis, dubbing, translation previews, dialogue editing, speech previews, organizations, and account usage are all represented. Minor lifecycle gaps remain, such as no obvious asset/project delete or job cancellation tools, but most core workflows can be completed without dead ends.
Maintenance
Related MCP Connectors
Generate and edit images, video, voice, lip-sync and 3D models from your AI agent.
Generate lip-synced talking and singing videos from images or videos and audio.
Create and manage cinematic AI video renders through the Future Video Studio Agent API.
Create and edit videos, images, voiceovers, music, and avatars with the VideoGen API.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to generate AI avatar videos, manage templates, and work with assets through natural language commands via the HeyGen API.7MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI video generation from text prompts, status monitoring, and video management through the Sisif AI Video API.1MIT

lipdub-mcpofficial
AlicenseAqualityBmaintenanceEnables AI agents to lip-sync video to a different audio track via LipDub 2, including creating renders, checking statuses, and retrieving results.512 npmMIT- AlicenseNot gradedqualityCmaintenanceEnables AI agents to generate images, videos, and lip-sync media, and to query wallet balances via the Open Generative Studio instance.MIT