Skip to content

Ask AI

Ask anything about Destesi — setup, products, APIs.

Powered by Claude. Answers may be wrong — always verify against the docs.

Reference

This page documents Studio’s real surface: the HTTP endpoints the web app calls, the run lifecycle, and the environment that configures the service.

The public API is session-authenticated through suite single sign-on. Browser requests carry the Studio session cookie established at GET /v1/sso/callback; the server validates it against identity and scopes every query to your workspace.

Endpoint Purpose
GET /v1/sso/callback Redeems the SSO grant and sets the Studio session.
GET /v1/auth/me Returns the signed-in account (id, email, name).
POST /v1/auth/logout Clears the Studio session.

Service-to-service callbacks live under /v1/controller/* and are gated by a shared controller secret — when that secret is unset, those routes return 404 and are invisible. They are used by Studio’s worker, not by you.

Endpoint Purpose
GET /healthz Cheap liveness check. Returns {"status":"ok"}.
GET /readyz Dependency check (database + queue). Returns 200 when healthy, 503 (status: degraded) with per-check detail when not.
Endpoint Purpose
GET /v1/setup/readiness What still needs connecting before Studio is fully usable in this workspace.
GET /v1/features Which optional capabilities this deployment has enabled.
GET /v1/blocks Browse-only catalog of text effects, transitions, VFX, stickers, and audio-reactive blocks.
GET /v1/worker/status Whether the build queue is being drained — what the worker banner reads.
Method & path Purpose
POST /v1/projects Create a project from a prompt. Creating it also enqueues the first build.
GET /v1/projects List your workspace’s projects.
GET /v1/projects/{id} Fetch one project.
GET /v1/projects/{id}/current Fetch the project’s current version — the project-first read the editor opens with.
PATCH /v1/projects/{id} Update a project.
DELETE /v1/projects/{id} Delete a project.
GET /v1/projects/{id}/variants List a project’s language variants.
POST /v1/projects/{id}/variants Create a variant.
Method & path Purpose
POST / GET /v1/templates Create or list templates.
GET / PATCH / DELETE /v1/templates/{id} Fetch, update, or delete one.
POST /v1/templates/{id}/duplicate Copy a template as a starting point.
POST / DELETE /v1/templates/{id}/logo Upload or clear the template’s logo.
POST / DELETE /v1/templates/{id}/background Upload or clear the template’s background.
GET / POST /v1/templates/{id}/rules List or add rules that decide when parts of the template apply.
PATCH / DELETE /v1/templates/{id}/rules/{ruleId} Update or remove a rule.
POST / GET /v1/assets Upload to, or list, the workspace asset library (images and audio, including music tracks).
GET / DELETE /v1/assets/{id} Fetch or delete one asset.
Method & path Purpose
POST /v1/projects/{id}/runs Start a run. Accepts an optional language_codes array to fan out one run per language.
GET /v1/projects/{id}/runs List a project’s runs.
GET /v1/projects/{id}/runs/{run_id} Fetch one run.
POST /v1/projects/{id}/runs/{run_id}/cancel Cancel an in-flight run.
POST /v1/projects/{id}/runs/{run_id}/retry Re-queue a failed or cancelled run.
POST /v1/projects/{id}/runs/{run_id}/approve Approve a run — registers the video + thumbnail in Drive.
GET /v1/runs/{run_id}/production Fetch the editable production document (scenes, image and audio URLs, render link, stale flag).
POST /v1/runs/{run_id}/duplicate Clone a run into a different aspect ratio (reuses images, re-renders).
PATCH /v1/runs/{run_id} Update a run’s label.
DELETE /v1/runs/{run_id} Delete a run and its scenes, renders, and publishes.
GET /v1/projects/{id}/artifacts/{run_id}/{step_index} Signed link to one pipeline step’s artifact.

Changing a finished video’s shape is a three-call flow, because a re-render is not free and you should see what it will cost before it starts.

Method & path Purpose
POST /v1/runs/{run_id}/aspect-change/preflight What changing the aspect would do — the check the web app shows before you confirm.
POST /v1/runs/{run_id}/aspect-change Start the change.
POST /v1/runs/{run_id}/aspect-change/{op_id}/retry-preview Retry the preview render for an in-flight change.

POST /v1/projects/{id}/runs with a language_codes array creates a variant per code (the first becomes primary) and enqueues a run per variant in parallel. The response carries the created ids:

{
"run_ids": ["…", "…"],
"variant_ids": ["…", "…"],
"language_codes": ["en", "es"]
}

Omit language_codes and the single-run shape ({ "run_id": "…" }) is returned.

A run advances through the pipeline and ends awaiting your approval:

queued → running → awaiting_approval → approved

A run can also reach failed or cancelled; both can be retried, which resets the run to queued and re-queues it.

Once a run reaches awaiting_approval, its scenes are editable. The web app’s chat-driven editor calls these; each tool endpoint records an asynchronous operation you can poll.

Method & path Purpose
POST /v1/runs/{run_id}/tools/regen_scene_image Regenerate one scene’s image.
POST /v1/runs/{run_id}/tools/regen_all_images Regenerate every scene’s image.
POST /v1/runs/{run_id}/tools/regen_scene_narration Re-voice one scene.
POST /v1/runs/{run_id}/tools/regen_all_narration Re-voice every scene with a new voice.
POST /v1/runs/{run_id}/tools/swap_voice Swap the narration voice.
POST /v1/runs/{run_id}/tools/edit_script Edit the script.
POST /v1/runs/{run_id}/tools/render_preview Render a fresh preview.
POST /v1/runs/{run_id}/tools/bundle_render Render every aspect ratio at once as a bundle.
POST /v1/runs/{run_id}/tools/set_video_style_preset Set the video’s style preset.
POST /v1/runs/{run_id}/tools/set_video_vibe Apply a vibe bundle (style, transitions, effects) across the video.
POST /v1/runs/{run_id}/tools/set_scene_vibe Apply a vibe bundle to one scene.
GET /v1/tools/ops/{op_id} Poll an operation’s state.
POST /v1/runs/{run_id}/tools/ops/{op_id}/retry Retry a failed operation.

Studio also exposes finer-grained scene tools — text effects, transitions, VFX, stickers, audio-reactivity, and image-source policy (set_scene_image_source, set_video_image_source) — under the same /v1/runs/{run_id}/tools/* prefix, plus direct scene editing:

Method & path Purpose
PATCH /v1/runs/{run_id}/scenes/{scene_id} Edit a scene field directly (e.g. duration).
POST /v1/runs/{run_id}/scenes Insert a scene.
DELETE /v1/runs/{run_id}/scenes/{scene_id} Delete a scene.
POST /v1/runs/{run_id}/scenes/{scene_id}/duplicate Duplicate a scene.
POST /v1/runs/{run_id}/scenes/reorder Reorder scenes.
POST /v1/runs/{run_id}/scenes/{scene_id}/image Upload your own image for a scene.
POST /v1/runs/{run_id}/scenes/{scene_id}/image-from-url Use an image from a URL for a scene.
POST /v1/runs/{run_id}/scenes/transitions Set the transition on every scene at once.
POST /v1/runs/{run_id}/scenes/durations Set the duration on every scene at once.
POST /v1/runs/{run_id}/scenes/{scene_id}/lock / DELETE …/lock Lock a scene against regeneration.
POST /v1/runs/{run_id}/rollback Revert the scene changes from a prior operation.
Method & path Purpose
PUT /v1/runs/{run_id}/music/asset Attach a track from the asset library as the background music.
PATCH / DELETE /v1/runs/{run_id}/music Adjust the music volume against the narration, or clear the track.
POST / PATCH / DELETE /v1/runs/{run_id}/logo Set, reposition, or clear a logo watermark.
GET /v1/runs/{run_id}/renders List a run’s renders, newest first.
GET /v1/runs/{run_id}/captions.srt Export SubRip captions.
GET /v1/runs/{run_id}/transcript.json Export a structured transcript.
POST / DELETE /v1/runs/{run_id}/share Mint or clear a public share link.
GET /v1/share/{token} Public, token-authenticated view of a shared run.
POST /v1/runs/{run_id}/webhook/test Fire a test payload at the run’s configured webhook URL.

Studio proxies voice listing and previews so the web editor doesn’t need a separate Text-to-Speech session:

Method & path Purpose
GET /v1/voices List the voices available to the workspace.
GET /v1/voices/{voice_id}/preview Stream a voice preview sample.

When no voice is chosen, Studio resolves the workspace default (Aria).

Method & path Purpose
POST /v1/chat The chat home — an NDJSON stream.
POST /v1/chat/resume Resume a turn that paused for your approval.
GET /v1/conversations List saved conversations.
GET /v1/conversations/{id}/messages Page one conversation’s history.
PATCH / DELETE /v1/conversations/{id} Rename or delete a conversation.
GET / POST /v1/runs/{run_id}/messages Read or append the per-video editor chat.
POST /v1/runs/{run_id}/chat/production The production agent turn for a video.

Publishing to social channels is wired and workspace-scoped. It targets the social accounts you’ve connected in Connect. A video must be approved and have a render before it can be published.

Method & path Purpose
POST /v1/runs/{run_id}/publish Schedule or immediately publish to one or more connected social accounts.
GET /v1/runs/{run_id}/publishes List a video’s publish records and their state.
GET /v1/renders/{render_id}/publishes List publishes for one specific render.

Supported channels: YouTube, TikTok, Instagram, Facebook, Threads, LinkedIn. Automatic retries are capped at four attempts (backing off roughly 2, 10, and 30 minutes) and only apply to failures that occur before anything reaches the platform — once the upload has started, the attempt is terminal so a retry can never produce a second public post.

Method & path Purpose
POST /v1/source/github Turn a repo URL into a project and its first build. Body: { "repo_url": "https://github.com/owner/repo", "workspace_id": "…", "workspace_slug": "…" }, plus the optional language_codes, aspect_ratio, and voice fields the prompt path accepts.

The GitHub credential is resolved per request from Connect, scoped to workspace_slug. Public repositories work with no connection; to read private repositories, connect GitHub in Connect for the workspace. Error mapping: an unknown repo returns 404; a GitHub or credential-lookup failure returns 502; an unparseable URL returns 400.

Method & path Purpose
GET /v1/promos List saved promo compositions for the workspace.
GET /v1/promos/{id} Fetch a saved promo with fresh signed URLs.

Studio runs as two processes — an HTTP API and a background worker — plus a web front end. Video rendering happens on Studio’s own internal render backend; it is not a separate product and there is nothing for you to sign into or configure for it. The variables below configure the two Studio processes.

Variable Purpose Default
STUDIO_API_ADDR API listen address :9104
STUDIO_DATABASE_URL Postgres DSN (schema studio) unset → database-backed routes fail until set
STUDIO_REDIS_URL Job queue connection redis://localhost:6379/4
STUDIO_IDENTITY_API_URL Identity host for SSO http://localhost:9091
STUDIO_WEB_URL Post-SSO redirect target http://localhost:4332
STUDIO_WEB_URL_ALLOWLIST Allowed post-redeem redirect origins (comma-separated) unset
STUDIO_CORS_ALLOWED_ORIGINS Permitted request origins (comma-separated) unset
IDENTITY_CONTROLLER_SECRET Bearer for /v1/controller/* callbacks unset → controller routes return 404
TTS_API_URL Text-to-Speech host (voice proxy) http://localhost:9098
CHAT_API_URL Chat host http://localhost:9102
CONNECT_API_URL Connect host (per-workspace credentials) http://localhost:9105
GITHUB_API_URL GitHub REST base (override for GitHub Enterprise) https://api.github.com
DRIVE_API_URL Drive host (artifact registration) http://localhost:9106
SUITE_TOOL_SECRET Bearer shared with Drive unset → Drive registration disabled

The worker drains the job queue and runs the pipeline. In addition to the shared STUDIO_REDIS_URL, STUDIO_DATABASE_URL, and peer-service URLs above, it reads:

Variable Purpose
STUDIO_API_URL Callback base to the API
IMAGEGEN_API_URL Image-generation host
STUDIO_STOCK_ENABLED Kill switch for stock-photo lookup (default on)
STUDIO_CACHE_DIR Local cache directory
STUDIO_IMAGEGEN_POLL_TIMEOUT / STUDIO_RENDER_POLL_TIMEOUT / STUDIO_TTS_POLL_TIMEOUT / STUDIO_JOB_TIMEOUT Per-step and per-job timeouts

Studio’s schema lives in the studio Postgres schema. Apply migrations with the bundled command, which reads STUDIO_MIGRATE_DATABASE_URL (falling back to STUDIO_DATABASE_URL):

Terminal window
cd apps/studio/api && go run ./cmd/migrate up
Terminal window
# From the suite root — start the database, queue, and object store first:
make dev-db
# Then, in separate shells:
make dev-studio-api # HTTP API on :9104
make dev-studio-worker # pipeline worker
make dev-studio-web # web app on :4332
# Health check:
curl -s http://localhost:9104/healthz
# => {"status":"ok"}

The worker calls peer services (Chat, Text-to-Speech, Image generation). Start the ones you need with their own make dev-* targets.