Programmatic access to the mini-lesson video generator (deployed at https://videogen.simonsays.hk). Any authorized agent can create a narrated video from text, a shared lessonRecorder link, or uploaded files — then download the MP4, VTT captions and a self-contained HTML player (with optional per-module quiz). The same service powers the human web UI at /.
Auth: send X-API-Key: <token> or Authorization: Bearer <token> on every /api/* call. This page and /api are public so you can read this before authenticating. Ask the service owner for a token; tokens are secrets — never put them in shared code.
POST /api/generate (multipart/form-data)
outline text — pasted notes/script/transcript (or upload a .pptx / PDF / DOCX)
title optional video title
brief optional — answers to clarifying questions (see /api/clarify)
build=1 optional — also start rendering the MP4 right away (default 0)
voice narrator | trustworth | simon (default narrator)
→ { "project": "ab12cd34ef", "slides": [...], "deckUrl": "/projects/ab12cd34ef/deck.html", "build": "queued" }
GET /api/status/<project>
→ { "step": "tts"|"capture"|"render"|"done", "done": false|true,
"log": "…live build log…", "video": "/projects/<id>/video/video.mp4" }
GET /projects/<id>/video/video.mp4 # the narrated MP4 (CRF-18, burned captions)
GET /projects/<id>/video/captions-<voice>.vtt # WebVTT captions
GET /projects/<id>/player.html # standalone HTML player (chapters + optional quiz)
GET /view/<id> # human share page
Or build separately: POST /api/build (project, voice) → poll /api/status/<project>. The render runs in the background and takes ~1–4 min; qa_frames.py runs before encoding and the build fails loudly if any pixel gate fails.
| Method / path | Purpose |
|---|---|
GET /api | Service discovery (this doc link, version). |
POST /api/linkfetch | url = a recorder.aitutor.ink/s/… share link → {title, lang, transcript}. Pass the transcript as outline. |
POST /api/clarify | outline, title → ≤4 clarifying questions the agent/user should answer before generating. |
POST /api/generate | Create a lesson from outline/files/pptx. Returns the project id + slides. build=1 auto-starts the render. |
POST /api/save | JSON slide edits {project, slides:[{seq,title,kicker,kind,bullets[],text,script,emotion}]} → re-renders the deck. |
POST /api/chat | Natural-language edit {project, prompt, slide?} — returns updated slides + a change summary. |
POST /api/quiz/draft | Draft one MCQ per module from the lesson → stores quiz.json. |
POST /api/quiz/save | {project, include, quiz:[{slide, question, options[], explanation}]} — mark the correct option with a trailing * in its line. |
GET /api/quiz/<project> | Current quiz + include flag. |
POST /api/build | Start rendering: project, voice. |
GET /api/status/<project> | Build progress + live log + final video path. |
POST /api/player | Build the standalone HTML player: project, voice → {url, embed, quizItems}. |
# 1) generate + auto-build from pasted notes
curl -s -X POST https://videogen.simonsays.hk/api/generate \
-F "title=How to find a research gap" \
-F "outline=Two kinds of problems: broad and specific
The specific problem is stated near the end of the introduction
Work backwards to the broader issue facing the community" \
-F "build=1"
# 2) poll until done
curl -s https://videogen.simonsays.hk/api/status/PROJECT_ID
# 3) fetch the outputs
curl -sL https://videogen.simonsays.hk/projects/PROJECT_ID/video/video.mp4 -o video.mp4
curl -s https://videogen.simonsays.hk/projects/PROJECT_ID/player.html -o player.html
import requests, time
BASE = "https://videogen.simonsays.hk"
# shared recording link → transcript as source material
txt = requests.post(f"{BASE}/api/linkfetch",
data={"url": "https://recorder.aitutor.ink/s/XXXX"}).json()["transcript"]
r = requests.post(f"{BASE}/api/generate", data={
"title": "Finding the research gap", "outline": txt, "build": "1"})
proj = r.json()["project"]
while True:
st = requests.get(f"{BASE}/api/status/{proj}").json()
if st.get("done"): break
time.sleep(3)
video = requests.get(f"{BASE}/projects/{proj}/video/video.mp4").content
page = requests.get(f"{BASE}/projects/{proj}/player.html").text
project id = one session; outputs are reachable while the session volume persists.VIDEOGEN_API_KEY is configured, /api/* requires X-API-Key: <token> or Authorization: Bearer <token> (constant-time compare). Unauthorized calls return 401. /api and /api/docs stay public.{error: "…"} with HTTP 400/404/409/422/502.videoGen · decktier Lane-A pipeline · source: tesolchina/videoGen-platform (decktier/webapp)