WideCast.ai

Read a video's structured scene data — POST /v1/video_data

Synchronous, free. First step for data-first scene audit/edit — call this before /v1/scene_geometry / /v1/modify_scene / /v1/scene_inspector. Returns the full annotated scene tree (current mediaUrl, narrator config, Remotion spec metadata) for a topic_id.

Recommended chain: video_data/v1/scene_geometry (cheap layout audit) → /v1/modify_scene. Use /v1/scene_inspector only as an expensive last resort when you need browser truth or a live screenshot.

URL-RESPONSE CONTRACT (default delivery_mode="download_url"). The HTTP response is a small JSON envelope; the full video_data tree (annotated segments[], scene_identity, global_settings, Remotion spec metadata) is published to a temporary public JSON file on origin.widecast.ai and the envelope carries data.url + data.bytes + data.expires_at + data.ttl_seconds=900 (15-min TTL) plus a 3-step instructions block. The agent must curl <data.url> -o video_data.json and Read locally — the full tree is NOT inlined in the HTTP response. This bypasses MCP per-tool-call output caps that previously truncated 50–300 KB payloads mid-JSON. Every call publishes a NEW unique file (token = 16 hex chars), so URLs are never reused — matches the realtime semantics of video data. Host is origin.widecast.ai (CF-bypassed) + ?v=<mtime> cache-bust. Server only responds AFTER the JSON is fsynced + atomically renamed to its final path, so the URL is guaranteed readable when the agent fetches it (no race). Operators can flip back to legacy inline mode via env flag WIDECAST_VIDEO_DATA_DELIVERY_MODE=inline_content.

Internal poster diagnostics are stripped by default. Per-segment remotion_poster_file / remotion_poster_url / remotion_poster_version / remotion_poster_state / remotion_poster_exists / remotion_poster_warnings (and their copies inside agent_meta.remotion_spec) describe the server-side {voice_file}_overlay_poster.png used by /v1/scene_inspector. Pass include_diagnostics: true to surface them for server / debug audits.

The endpoint mirrors the same engine the dashboard's scene editor uses on open — A/B-roll rebalance + ensure background music + persist if changed — so the data matches what the user sees in https://widecast.ai/#scene_editor?topic_id=… exactly.

To keep MCP payloads usable, the API trims per-segment words timing arrays, top-level captions, plus internal preview-cache fields (savedVideos, savedImages, _previewInstanceId, _remotionSpecFetching, _forceNarratorRefit). UI routes still get full data; this is the agent-safe slim view.

POST/v1/video_data

📜 Audit a video — list every scene + Remotion spec status

Default response. Paste a topic_id (the id returned by /v1/create_video) to see scene_identity, every scene's voice_file (stable UID), current mediaUrl/mediaType, narrator config, and remotion_spec_url (cache-busted) + remotion_spec_state (ready/missing/disabled). Spec content is NOT inlined — fetch remotion_spec_url only when state is ready and you need object boxes.

Loading…

🔬 Server/debug audit — include remotion_poster_*

Opt back into the diagnostic poster keys per-segment (file, url, version, state, exists, warnings). For server/debug audits only — agents don't act on these.

Loading…


Scene identity rule

The response includes a machine-readable scene_identity block. Agents must follow it:

Field Stable? Use for
voice_file (scene_uid) Yes Selecting a scene in /v1/modify_scene and /v1/scene_inspector. Also the base of the Remotion spec filename {voice_file}_spec.json.
id / order_id / scene_index No Display / current ordering only. May change after reorder/add/delete.

When in doubt, use voice_file. Don't persist segment.id between calls.


Coordinate spaces

Two coordinate spaces appear in segment data — they are not interchangeable:

Space Width × Height Where it appears
Remotion canvas 720 × 1280 All remotion_spec content + remotion.* modify_scene fields
Legacy editor preview 280 × 498 overlay.caption.rect, overlay.narrator.rect, legacy overlay layout

Pass coordinate_space: "canvas" or "preview" to /v1/modify_scene when sending remotion.group.rect.

The same map is bundled into agent_meta.coordinate_spaces on every segment for quick consumption.


Request

POST /v1/video_data
Authorization: Bearer wc_live_REPLACE_ME
Content-Type: application/json

{ "video_id": "widecastABCDEFGHIJKL" }

Field reference

Field Type Required Description
video_id string yes Topic id from /v1/create_video / scene editor. Accepts widecast..., gubo..., or current ids. Same id used by /v1/status, /v1/export_video, /v1/modify_scene, /v1/scene_inspector.
include_diagnostics boolean no Default false. When true, per-segment remotion_poster_* diagnostic keys (and their copies inside agent_meta.remotion_spec) are returned. For server / debug audits only.

Response — 200 OK (default download_url mode)

// HTTP response envelope — small, fits any MCP runtime.
{
  "object":         "video_data",
  "id":             "widecastABCDEFGHIJKL",
  "topic_id":       "widecastABCDEFGHIJKL",
  "delivery_mode":  "download_url",
  "skill_required": "load_widecast_editing_skill_first",
  "review_url":     "https://widecast.ai/#scene_editor?topic_id=widecastABCDEFGHIJKL",
  "data": {
    "url":         "https://origin.widecast.ai/downloads/<co>/widecastABCDEFGHIJKL/video_data/3f0a8b2c91d4e57f.json?v=1782900123",
    "mime_type":   "application/json",
    "bytes":       182394,
    "expires_at":  "2026-06-30T18:32:03Z",
    "ttl_seconds": 900
  },
  "instructions":   "FETCH THE VIDEO DATA NOW (3-step setup): 1) mkdir -p ./.widecast-video-data && cd ./.widecast-video-data  2) curl -fsSL '<data.url>' -o video_data.json  3) Read('./.widecast-video-data/video_data.json')",
  "next_action":    "fetch_and_read_video_data_json",
  "meta": {
    "delivery_mode":   "download_url",
    "request_id":      "req_abcd…",
    "freshness":       "fresh-per-call (token unique, ?v=mtime cache-bust)",
    "experiment_note": "Flip back with WIDECAST_VIDEO_DATA_DELIVERY_MODE=inline_content."
  },
  "request_id":     "req_abcd…"
}

Published JSON file content (fetch from data.url)

{
  "object":         "video_data",
  "id":             "widecastABCDEFGHIJKL",
  "topic_id":       "widecastABCDEFGHIJKL",
  "aspect_ratio":   "portrait",
  "title":          "Why your teen should get a driver's license at 16",
  "language":       "English",
  "total_segments": 6,
  "total_duration": 92.4,
  "scene_identity": {
    "stable_scene_id_field": "voice_file",
    "order_field":           "id",
    "notes": [
      "voice_file is the stable per-scene UID.",
      "segment.id is current display/order and may change after reorder/add/delete.",
      "The Remotion spec for a scene is {voice_file}_spec.json."
    ]
  },
  "segments": [
    {
      "id":                       "0",
      "order_id":                 "0",
      "scene_index":              0,
      "voice_file":               "XcR0k",
      "scene_uid":                "XcR0k",
      "type":                     "A-roll",
      "text":                     "You should let your teen get a driver's license at 16.",
      "talking_point":            "Independence is a foundation skill.",
      "visual":                   "Teen holding car keys, soft daylight.",
      "quote":                    "",
      "keyword":                  "license",
      "duration":                 8.2,
      "mediaUrl":                 "https://widecast-assets.s3.us-west-1.amazonaws.com/.../scene01.jpg",
      "mediaType":                "image",
      "thumbnailUrl":             "https://widecast.ai/downloads/.../thumb_01.jpg",
      "videoTrim":                {},
      "overlay": {
        "caption":  { "rect": { "x": 20, "y": 360, "w": 240, "h": 96 } },
        "narrator": { "rect": { "x": 80, "y": 300, "w": 120, "h": 180 } }
      },
      "narrator": {
        "name": "Sarah", "voice_id": "v_clone_42", "face_id": "f_clone_42",
        "audio_url": "...", "video_url": ""
      },
      "remotion_spec":           "XcR0k_spec.json",
      "remotion_spec_file":      "XcR0k_spec.json",
      "remotion_spec_url":       "https://widecast.ai/downloads/<company_id>/widecastABCDEFGHIJKL/XcR0k_spec.json?v=1748293012",
      "remotion_spec_version":   "1748293012",
      "remotion_spec_exists":    true,
      "remotion_spec_state":     "ready",
      "agent_meta": {
        "stable_scene_id_field": "voice_file",
        "stable_scene_id":       "XcR0k",
        "order_field":           "id",
        "order_value":           "0",
        "scene_index":           0,
        "remotion_spec": {
          "file":     "XcR0k_spec.json",
          "url":      "https://widecast.ai/downloads/<company_id>/widecastABCDEFGHIJKL/XcR0k_spec.json?v=1748293012",
          "state":    "ready",
          "exists":   true,
          "version":  "1748293012"
        },
        "coordinate_spaces": {
          "canvas":  { "width": 720, "height": 1280, "used_by": "remotion_spec.*, modify_scene remotion.* fields" },
          "preview": { "width": 280, "height": 498,  "used_by": "overlay.caption, overlay.narrator (legacy)" }
        }
      }
    },
    {
      "id":                       "1",
      "order_id":                 "1",
      "scene_index":              1,
      "voice_file":               "Z9p2m",
      "scene_uid":                "Z9p2m",
      "type":                     "B-roll",
      "text":                     "Here's why responsibility starts behind the wheel.",
      "duration":                 12.7,
      "mediaUrl":                 "https://pexels.com/.../teen_driving.mp4",
      "mediaType":                "video",
      "brollUrl":                 "https://pexels.com/.../teen_driving.mp4",
      "thumbnailUrl":             "https://pexels.com/.../teen_driving_thumb.jpg",
      "remotion_spec":            "none",
      "remotion_spec_file":       "Z9p2m_spec.json",
      "remotion_spec_url":        "",
      "remotion_spec_exists":     false,
      "remotion_spec_state":      "disabled",
      "narrator": {}
    }
  ],
  "global_settings": {
    "aspectRatio":       "portrait",
    "voice_type":        "clone",
    "avatar_type":       "clone",
    "last_voice_type":   "clone",
    "last_avatar_type":  "clone"
  },
  "review_url": "https://widecast.ai/#scene_editor?topic_id=widecastABCDEFGHIJKL",
  "request_id": "req_abcd…"
}

Per-segment field reference

Field Description
voice_file / scene_uid Stable per-scene UID. Pass to /v1/modify_scene and /v1/scene_inspector. Base of {voice_file}_spec.json.
id / order_id / scene_index Current display/order only — UNSTABLE.
type A-roll (narrator on screen), B-roll (background only), thumbnail, or empty.
text, talking_point, visual, quote, keyword Narration + creative direction signals — useful to ground a generated overlay image.
duration Seconds.
mediaUrl, mediaType, thumbnailUrl, videoTrim Currently-shown asset on the scene.
overlay.caption, overlay.narrator Legacy 280×498 editor preview coords.
narrator {name, voice_id, face_id, audio_url, video_url} when set.
remotion_spec Per-scene Remotion spec token. "none" means the user intentionally disabled the overlay — agents must NOT auto-edit or re-enable unless asked.
remotion_spec_file Canonical {voice_file}_spec.json.
remotion_spec_url Cache-busted https://widecast.ai/downloads/{company_id}/{topic_id}/{voice_file}_spec.json?v={mtime}. Empty when state is missing or disabled.
remotion_spec_version mtime token used for cache-busting (matches ?v=).
remotion_spec_exists Boolean — file present on disk.
remotion_spec_state ready (file exists), missing (expected but not built), disabled (user turned the overlay off).
agent_meta Same metadata bundled for quick consumption — stable_scene_id, order_value, scene_index, remotion_spec block, coordinate_spaces.

The Remotion spec content is NOT inlined in this response. It can carry large base64 images that blow MCP payload budgets. Fetch remotion_spec_url only when remotion_spec_state == "ready" and you actually need object-level overlay boxes.

Error responses

error.code HTTP When
missing_field 400 video_id is empty.
video_not_found 404 No video with this id on the account.
script_not_ready 409 Video is still processing or never had a script generated. Poll /v1/status until status=="completed".
script_parse_failed 502 Stored video_script is malformed. Contact support with request_id.
video_data_publish_failed 500 Response tree was assembled but could not be persisted to disk. Retry with the same video_id; if it persists, contact support with request_id.
missing_api_key / invalid_api_key 401 Auth.

SDK examples

Python — data-first audit then edit

import json
import urllib.request
from widecast import Widecast

client = Widecast()
envelope = client.video_data("widecastABCDEFGHIJKL")

# URL-response mode (default): fetch the published JSON file.
with urllib.request.urlopen(envelope["data"]["url"]) as resp:
    data = json.load(resp)

for seg in data["segments"]:
    print(f"Scene {seg['scene_index']} ({seg['type']}, {seg['duration']:.1f}s)")
    print(f"  voice_file: {seg['voice_file']}")
    print(f"  spec state: {seg['remotion_spec_state']}")
    print(f"  text:       {seg['text'][:80]}")

target = next(s for s in data["segments"] if "license" in (s.get("keyword") or ""))
client.modify_scene(
    data["id"],
    by="voice_file",
    value=target["voice_file"],
    fields=[{"field_name": "mediaUrl", "value": "https://example.com/new.jpg"}],
)

TypeScript

import Widecast from "@widecast/sdk";

const client = new Widecast();
const envelope = await client.video_data("widecastABCDEFGHIJKL");
const data = await (await fetch(envelope.data!.url)).json();
for (const seg of data.segments) {
  console.log(`Scene ${seg.scene_index} ${seg.type} ${seg.duration?.toFixed(1)}s voice_file=${seg.voice_file}`);
}

MCP / agent recipe

{ "name": "widecast_video_data", "arguments": { "video_id": "widecastABCDEFGHIJKL" } }
// → envelope contains data.url; agent must:
//     mkdir -p ./.widecast-video-data && cd ./.widecast-video-data
//     curl -fsSL '<data.url>' -o video_data.json
//     Read('./.widecast-video-data/video_data.json')
// → inspect segments; pick voice_file; then call widecast_modify_scene with by="voice_file".