WideCast Documentation
The complete reference for the WideCast.ai public API, SDKs, and integrations.
Looking for a 30-second pitch? Head to the WideCast homepage.
Quickstart
# 1. Create from plain-text script
RESP=$(curl -sS -X POST "https://widecast.ai/app/dashboard2/v1/create_video" \
-H "Content-Type: application/json" \
-d '{
"script_text": "Bạn nên cho con lấy bằng lái xe ngay khi 16 tuổi."
}')
VID=$(echo "$RESP" | jq -r .id)
# 2. Poll until completed
INTERVAL=5
until [ "$STATE" = "completed" ] || [ "$STATE" = "failed" ]; do
sleep $INTERVAL
STATUS=$(curl -sS "https://widecast.ai/app/dashboard2/v1/status/$VID")
STATE=$(echo "$STATUS" | jq -r .status)
INTERVAL=$(( INTERVAL * 3 / 2 < 60 ? INTERVAL * 3 / 2 : 60 ))
done
echo "Review at: $(echo "$STATUS" | jq -r .result.review_url)"
from widecast import Widecast
client = Widecast(api_key="wc_live_REPLACE_ME")
video = client.create_video(
script_text="Bạn nên cho con lấy bằng lái xe ngay khi 16 tuổi."
).wait() # auto-polls /v1/status with 5s→60s exp backoff
print(video.status, video.review_url)
import Widecast from "@widecast/sdk";
const client = new Widecast({ apiKey: "wc_live_REPLACE_ME" });
const v = await client.create_video({
script_text: "Bạn nên cho con lấy bằng lái xe ngay khi 16 tuổi.",
}).then(v => v.wait());
console.log(v.status, v.review_url);
v0.1.0 endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/v1/create_video |
POST | Submit a finished script (source=text), an idea brief (source=idea), a blog/article (source=blog), or an existing video/audio by URL or upload (source=video_url/video_file/audio_url/audio_file) for AI sourcing |
/v1/export_video |
POST | For output_type=scene videos, kick the final-MP4 renderer after review |
/v1/status/{id} |
GET | Universal poll endpoint for any async task |
| Webhooks | (out-of-band) | Pass callback_url in create_video — WideCast POSTs events to your URL instead of you polling |
/openapi.json / /openapi.yaml |
GET | This spec served from the host |
Reference
- Use WideCast with Claude / ChatGPT (no code):
use-with-ai.html— connect the MCP server + add the writing Skills, then just say "make me a video". - Live playground:
playground.html— submit + auto-poll + review-URL link in one click - OpenAPI 3.1 spec:
openapi.yaml(also athttps://widecast.ai/app/dashboard2/openapi.yaml) - Python SDK:
widecaston PyPI - JS/TS SDK:
@widecast/sdkon npm - MCP server (Claude / Cursor / Windsurf):
@widecast/mcp-server— toolscreate_video/get_status/export_video. - Authoring Skills:
widecast/skills/—video-script-writing,blog-writing,social-post-writing(best-practice guides the AI loads on demand). - LLM-friendly docs index:
llms.txt
Conventions
- ID format:
gubo<alphanumeric>(~20 chars). The internal server's new-script detection checks for the literal"gubo"substring — SDKs/clients must not strip it. - API key prefixes:
wc_live_* - Authentication: send your key as
Authorization: Bearer wc_live_.... When key enforcement is on, a missing/malformed/revoked key → HTTP 401 witherror.type = "authentication_error"anderror.code=missing_api_keyorinvalid_api_key. (Enforcement is server-toggled; while it's off, the pilot accepts unauthenticated calls.) - Object marker on every resource:
"object": "status","object": "list", etc. - Status enum (locked):
pending | processing | completed | failed - Error codes (locked, v0.1.0):
account_expired | credit_exhausted | render_failed | unknown_error | scenes_not_ready | export_failed | script_too_short | script_too_long | invalid_output_type | invalid_source | idea_too_short | missing_idea_text | blog_too_short | missing_blog_text | missing_video_url | missing_audio_url | missing_media_file | unsupported_media_url | media_too_long | file_too_large | missing_api_key | invalid_api_key | invalid_language | invalid_video_length | invalid_research_enabled - Input bounds (locked):
script_text(source=text) is 80–500 words (~20s–2 min, used verbatim).idea_text(source=idea) is 5–1000 words andblog_text(source=blog) is 30–3000 words (both interpretive — over-max auto-truncated, not rejected). Media sources (video_*/audio_*) have a 2-minute duration cap (media_too_long, all media) and uploads a 100 MB size cap (file_too_large). SDKs exportSCRIPT_MIN_WORDS/SCRIPT_MAX_WORDS/IDEA_MIN_WORDS/IDEA_MAX_WORDS/BLOG_MIN_WORDS/BLOG_MAX_WORDS/MEDIA_MAX_DURATION_SECONDS/MEDIA_MAX_FILE_BYTESconstants. - Inline media in
script_text(source=text): embed a direct image/video file URL (.png/.jpg/…or.mp4/.mov/…) next to the line it should illustrate — WideCast strips it from the narration and uses it as that scene's visual instead of auto-sourced B-roll. Page links (YouTube/TikTok watch URLs) aren't inlined — usesource=video_urlfor a whole clip. See Create-video → Inline images & video. - Enums (locked v0.1.0):
SOURCES(text,idea,blog,video_url,video_file,audio_url,audio_file),OUTPUT_TYPES(text,scene,video),LANGUAGES(English,Vietnamese),VIDEO_LENGTHS(short,normal). For media sourcesoutput_type="text"= Remake (transcript only). - Field-requirement parity (A38): every field constraint surfaces in 5 places — OpenAPI spec, SDK constants/types, this docs site's endpoint page, the playground UI (YAML + JS), and server enforcement (with a locked
error.code). Adding an endpoint without all five = drift.build.pyvalidates the YAML↔JS half automatically. - All timestamps are ISO 8601 UTC strings (e.g.
2026-05-19T17:30:00Z) - Every response carries
X-Request-Id— include it in any support ticket