StarReel Production APIStarReel 短剧产线 API
Turn a script into a finished, downloadable short-drama episode — programmatically. Drive the whole pipeline (storyboards → frames → video → final cut) from an AI agent over MCP, or from your own code over REST. One key powers both. 把剧本变成一集可下载的成片 — 全程可编程。用 AI agent 走 MCP,或从你自己的代码走 REST,驱动整条产线(分镜 → 帧 → 视频 → 成片)。一把 Key 通用。
The pipeline产线一览
One episode, the full pipeline — nothing skipped. Set the raw script, let AI rewrite it into a shootable draft (you can review & edit), extract the cast/scenes/props, lock character portraits (the consistency anchor), then storyboards → frames → video → final cut. Each spending stage gives you a quote first; you confirm, then it runs in the background. 一集短剧,走完整工作流、不跳步。设原始剧本 → AI 改写成可拍稿(可审阅/改稿)→ 提取角色/场景/道具 → 锁角色定妆图(一致性锚)→ 分镜 → 首帧 → 视频 → 成片。每个花钱阶段先报价,你确认后后台执行。
create_drama; every image / video / final cut then uses it. Don't change it mid-way or already-rendered content won't match (defaults to 9:16 if unset). ② Each shot runs 5–7s on purpose (tuned for AI video generation) — don't mistake a "long" shot for a bug and re-split. generate_storyboards replaces ALL existing shots (rendered frames wasted, re-paid); with shots already present the server blocks it unless you pass confirm_replace=true.
两条锁定纪律。① 画幅比例 drama 级锁定 — create_drama 时定一次,之后所有出图/出视频/成片都用它;别中途改,否则已生成内容画幅不一致(不设默认 9:16)。② 每镜 5–7 秒是刻意的(为 AI 出视频优化)— 别把「镜偏长」当 bug 就重拆。generate_storyboards 会**替换整集所有分镜**(已出图白费、要重花钱),已有分镜时后端会拦、需带 confirm_replace=true。剧本 create_drama → set_script(原始) → rewrite_script(AI改写) → [get_script / edit_rewritten_script]
→ extract_assets(角色/场景/道具) → generate_portraits_and_sheets(定妆图+设定图) → assign_voices(分配音色·配音前必做)
制作 → storyboards → frames → videos → compose → 成片.mp4(COS 下载链接)
免费(DB/ffmpeg):create_drama · set_script · get_* · edit · update设定 · compose · 多画幅 · 音效/特效/转场 · 交付物 按量后付·无报价(不足即402):rewrite · extract · tts配音 · 海报/封面/三视图 · 世界观/美术/色彩/动作等风格锁 · MV故事/剧本
报价·确认(quote_* + generate_*):storyboards · frames · videos · character_portraits · scene_images
项目类型:create_drama 传 project_type = drama(短剧) / ad(商业广告) / mv(音乐) / brand_film(品牌短片)
★广告(ad)专属必做:add_product 建产品库(广告主体)+ generate_product_sheet 出设定图,否则镜头产品漂移;MV:set_mv_lyrics→generate_mv_story→generate_mv_script
get_pipeline_status 按项目类型返回专属步骤(广告 build_product_library/set_cta,MV 歌词/故事)——查它就知道还差什么MCP — for AI agentsMCP — 给 AI agent
Claude Code, Cursor, and other MCP clients. One command, then your agent runs the pipeline itself.Claude Code、Cursor 等 MCP 客户端。一行命令,之后 agent 自己跑产线。
REST API — for your codeREST API — 给你的代码
Plain HTTPS from any language — /v1/produce/*. curl / Python / Node examples throughout.任意语言的普通 HTTPS — /v1/produce/*。全程 curl / Python / Node 示例。
Both paths share the same key, scopes, and billing (below). Base URL: https://api.shortreelai.com两条路径共用同一套 Key、scope 与计费(见下)。基址:https://api.shortreelai.com
Authentication鉴权
Create a long-lived API key in Settings → API Key (srk_live_…, shown once). You never send the key to business endpoints — you exchange it for a short 15-minute bearer token, then send that token. Re-exchange when it expires.
在 设置 → API Key 创建长期 Key(srk_live_…,只显示一次)。Key 不直接调业务端点 — 先换一枚 15 分钟短期令牌,再带令牌调用。过期就重新换。
curl -X POST https://api.shortreelai.com/v1/agent/token \
-H 'content-type: application/json' \
-d '{"api_key":"srk_live_..."}'
# 200
{ "code": 0, "data": {
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 900,
"scopes": "produce,read" } }import time, requests
BASE = "https://api.shortreelai.com"
API_KEY = "srk_live_..."
_tok = {"v": None, "exp": 0}
def token():
"""Exchange the API key for a 15-min token, cached until ~1 min before expiry."""
if _tok["v"] and time.time() < _tok["exp"] - 60:
return _tok["v"]
r = requests.post(f"{BASE}/v1/agent/token", json={"api_key": API_KEY})
r.raise_for_status()
d = r.json()["data"]
_tok["v"] = d["access_token"]
_tok["exp"] = time.time() + d["expires_in"]
return _tok["v"]
def auth():
return {"authorization": f"Bearer {token()}"}const BASE = "https://api.shortreelai.com";
const API_KEY = "srk_live_...";
let _tok = { v: null, exp: 0 };
// Exchange the API key for a 15-min token, cached until ~1 min before expiry.
export async function token() {
if (_tok.v && Date.now() < _tok.exp - 60000) return _tok.v;
const r = await fetch(BASE + "/v1/agent/token", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ api_key: API_KEY }),
});
if (!r.ok) throw new Error("token exchange failed: " + r.status);
const d = (await r.json()).data;
_tok = { v: d.access_token, exp: Date.now() + d.expires_in * 1000 };
return _tok.v;
}
export const auth = async () => ({ authorization: "Bearer " + (await token()) });Scopes授权范围
A key's power is set by the scopes you pick when creating it. Out-of-scope calls return 403.Key 权限由创建时选的 scope 决定,越权返回 403。
| scope | Unlocks解锁能力 |
|---|---|
read | Read-only: identity (GET /v1/me) and balance (GET /v1/entitlement).只读:身份(GET /v1/me)与余额(GET /v1/entitlement)。 |
produce | AI pipeline (/v1/ai/*): chat, image, TTS, video. Incurs charges.AI 产线(/v1/ai/*):文本、图片、语音、视频。会扣费。 |
localize | Overseas localization pipeline (used by the MCP tools).出海本地化产线(MCP 工具用)。 |
Billing — prepaid, no overdraft计费 — 先充值,不欠费
StarReel is prepaid. You need balance to generate, and the account never goes negative. Cost is authorized against your balance before the vendor runs; if you can't afford it the call returns 402 and no vendor cost is incurred. When the balance runs out mid-use, the account stops until you recharge. Usage is billed to the same balance as the web app.
StarReel 预付制。生成需有余额,账户永不为负。成本在厂商运行之前对余额预授权;付不起则 402 且不产生厂商成本。余额用尽即停,充值后恢复。用量计入与网页端同一套余额。
Path A · MCP setup路径A · MCP 接入
For AI agents. After setup, the agent discovers and calls the tools on its own — you just talk to it.给 AI agent。接入后 agent 自行发现并调用工具 — 你只管对它说话。
Claude Code
claude mcp add starreel -e STARREEL_API_KEY=srk_live_... -- npx -y @starreel/mcpCursor / other MCP clientsCursor / 其他 MCP 客户端
Add to your client's MCP config (e.g. mcp.json):加进客户端的 MCP 配置(如 mcp.json):
{
"mcpServers": {
"starreel": {
"command": "npx",
"args": ["-y", "@starreel/mcp"],
"env": { "STARREEL_API_KEY": "srk_live_..." }
}
}
}MCP tools — the pipelineMCP 工具 — 整条产线
Needs produce scope. Follow the full workflow in order — poll get_pipeline_status to see the 10 stages. Big-ticket stages (portraits / storyboards / frames / videos / scene-images) split into quote_* + generate_* so the agent shows you the quote first; other AI-generation steps have no quote — they meter by usage and return 402 mid-run if the balance can't cover them (never overdraft). Long stages run in the background.需 produce scope。照完整工作流按序推进,用 get_pipeline_status 看 10 步进度。大额阶段(定妆图/分镜/首帧/视频/场景图)拆成 quote_* + generate_*,agent 先给你报价;其余 AI 生成步无报价,按用量后付、余额不足执行中 402(不欠费)。长阶段后台异步。
get_* / edit / update_project_settings · compose_episode · get_final_cut / get_export · render_multi_aspect · generate_sfx / generate_effects / generate_transitions (local-library match) · generate_deliverables (ffmpeg re-cuts) · add_product / list_products. Metered (every AI generation): all images (portraits, storyboards, frames, scene & world images, character/prop sheets, posters, covers), all video (shots, scene groups, lipsync, edits/regen), TTS voiceover / voice swap / BGM, and all LLM text (rewrite, extract, art-bible, visual-lock, setting-brief, style/color/motion locks, MV story/script, subtitle translation). Stages with a quote_* are pre-quoted; the rest meter by usage and 402 if short.
免费 vs 收费一览。免费(纯 DB + ffmpeg,不调厂商):建剧 / set_script / 所有 get_* / 改稿 / update_project_settings · compose_episode 终拼 · get_final_cut / get_export · render_multi_aspect 多画幅 · generate_sfx / generate_effects / generate_transitions(本地库匹配)· generate_deliverables(ffmpeg 切规格)· add_product / list_products。收费(一切 AI 生成):所有出图(定妆·分镜·首帧·场景·世界观·三视图·海报·封面)、所有出视频(镜头·场景组·口型·编辑/重生)、TTS 配音/换音色/配乐、所有 LLM 文本(改写·提取·美术圣经·视觉锁·设定brief·风格/色彩/动作锁·MV故事/剧本·字幕翻译)。带 quote_* 的先报价;其余按用量后付、不足即 402。| Tool工具 | What it does作用 |
|---|---|
list_project_options | List project types / aspect ratios / video resolutions (labels + defaults) — call before create_drama to let the user choose. Free.列项目类型/画幅/分辨率的全部可选项(带标签+默认值)——建剧前调,给用户挑。免费。 |
create_drama | Create a drama (+ empty episodes); returns episode_ids. Pick project_type: drama / ad / mv / brand_film. Free.建剧(+空集),返回 episode_ids。可选 project_type:drama/ad/mv/brand_film。免费。 |
set_script | Set an episode's raw script (the input to AI rewrite). Free.设一集的原始剧本(AI 改写的输入)。免费。 |
rewrite_script | AI-rewrite raw → shootable draft (picks the rewriter by project_type). Metered text.AI 改写:原始 → 可拍稿(按类型选改写 agent)。文本后付。 |
get_script / edit_rewritten_script | Read raw + rewritten draft / edit the AI draft yourself. Free.读原始+改写稿 / 客户改 AI 稿。免费。 |
extract_assets | Extract characters / scenes / props (the consistency foundation). Metered text.提取角色/场景/道具(一致性地基)。文本后付。 |
quote_character_portraits / generate_character_portraits | Lock character portraits (a single identity image per character). Needed — but not enough on its own; also do sheets (next row).出角色定妆图(每角色单张身份图)。必需 — 但只有它不够,还要出设定图(见下一行)。 |
generate_character_sheets / generate_portraits_and_sheets | ★ Character sheets = the shot consistency anchor. Multi-view turnarounds that every shot frame & video references (2.5 uses their slices for the face + full-body wardrobe lock). Portraits alone → characters drift across angle / lighting / wardrobe. generate_character_sheets does the whole cast (skips any already sheeted, no double-charge); generate_portraits_and_sheets is the one-call standard — portraits first, then call again for sheets once portraits are ready (sheets need the portrait as anchor). Metered (image).★ 设定图 = 镜头一致性根锚。多视角 turnaround,每个镜头帧和视频都引用(2.5 用其切片做脸+全身服装锁)。只出定妆图 → 人物换角度/换光/服装会漂移。generate_character_sheets 批量出全剧(已有的自动跳过,不重复扣费);generate_portraits_and_sheets 一键标配 — 先出定妆图,就绪后再调一次出设定图(设定图需定妆图当锚)。收费(出图)。 |
quote_storyboards / generate_storyboards | Break the shootable draft into storyboards (shots).把可拍稿拆成分镜。 |
get_storyboards / get_pipeline_status | Review shots + frame/video readiness / see the 10-stage progress. Free.审阅分镜+帧/视频就绪度 / 看 10 步进度。免费。 |
| Storyboard QC / AI ops分镜质量/AI操作 | Two free gates (recommended before frames): run_precheck (moderation / readiness — catch shots the vendor will reject, before you pay) · get_health_report (duration overrun / motif coverage / problem shots). Then AI boosts (metered): autofill_storyboards (fill empty fields, doesn't overwrite existing) · enhance_shot_prompts & complete_ending_motifs — optional, not required, and they rewrite existing content — run BEFORE generate_frames or already-rendered images go stale.两个免费闸(出图前推荐):run_precheck(合规/敏感/就绪 — 把会被厂商拒的镜提前揪出,防白花钱)· get_health_report(时长超标/母题覆盖/问题镜)。再是 AI 增强(收费):autofill_storyboards(补空缺字段,默认不覆盖已有)· enhance_shot_prompts 与 complete_ending_motifs — 非必须,且会改写已有内容 — 务必 generate_frames 之前做,否则已出图陈旧需重生。 |
quote_frames / generate_frames | Generate frames for a whole episode (frame_type: first_frame default / last_frame / both).整集批量出帧(frame_type:默认 first_frame / last_frame / both)。 |
quote_shot_frame / generate_shot_frame | Redraw one frame of one shot — the right way to fix a shot that came out wrong. Keeps the identity/style anchors and the frame audit.重画某一镜的某一帧 —— 修某镜画面的正路,保留身份/画风锚与帧审计。 |
quote_videos / generate_videos | Generate the video for the whole episode (the big cost; quote == charge).整集出视频(大头;报价==扣费)。 |
compose_episode / get_final_cut / get_export | Merge into the final cut (free), fetch the download link + master status.终拼成片(免费)、拿下载链接+母版状态。 |
update_project_settings / create_drama | Set project settings (at creation or after). Beyond aspect / resolution / worldview brief / ethnicity / director style, now the whole project-settings page: consistency anchors (cinematography_prompt, art_bible, visual_lock, video_style_prompt/video_negative_prompt, motifs), audio (bgm_source own-vs-clip / bgm_volume_preset / use_clip_audio), subtitles (show_subtitles, bilingual, position, margin, animation), transitions. Free. (Internal pipeline/cost switches stay gated.)设项目设定(建剧时或建后)。除画幅/分辨率/世界观Brief/族裔/导演风格外,现覆盖项目设定页全部:整剧视觉一致性锚(cinematography_prompt 摄影DNA/art_bible 美术圣经/visual_lock 视觉锁定/video_style_prompt·video_negative_prompt 视频风格正负向/motifs 视觉母题)、音频(bgm_source 自有vs原生/bgm_volume_preset 音量/use_clip_audio 用视频原声)、字幕(show_subtitles/双语/位置/边距/动效)、转场。免费。(内部产线/成本开关仍不放行。) |
| Optional boosts可选增强 | generate_world_concept · generate_art_bible · extract_visual_lock · generate_color_script · generate_motion_templates · quote/generate_scene_images — drama-level consistency & style locks. All metered (world_concept = image; the rest LLM text; scene_images is quoted).generate_world_concept · generate_art_bible · extract_visual_lock · generate_color_script · generate_motion_templates · quote/generate_scene_images —— 剧目级一致性/风格锁。均收费(world_concept 出图;其余 LLM 文本;scene_images 有报价)。 |
| Read back读取/查询 | list_dramas · get_drama · get_characters · get_scenes · get_assets · get_jobs (queue progress) · get_cost_estimate · get_budget_status. All free.list_dramas(列剧)· get_drama · get_characters · get_scenes · get_assets · get_jobs(任务进度)· get_cost_estimate · get_budget_status。均免费。 |
| Upload your images上传自有图片 | upload_image · set_character_portrait · upload_shot_frame · upload_scene_image · upload_prop_sheet — auto-upload a local file to our COS + register as portrait/frame/scene/prop.upload_image · set_character_portrait · upload_shot_frame · upload_scene_image · upload_prop_sheet —— 本地图自动传 COS + 登记为定妆图/首尾帧/场景/道具。 |
| Audio音频 | assign_voices (assign every character a voice — required before TTS; voiceStyle is not auto-filled) · generate_tts (episode voiceover — required before final cut) · replace_shot_dialogue · generate_bgm · translate_subtitles. All metered — generate_tts is a required paid voiceover step before the final cut (not free like compose); voice swap / BGM / subtitle translation are metered too.assign_voices(给每个角色分配音色·配音前必做,音色不是自动填的)· generate_tts(整集配音·成片前必做)· replace_shot_dialogue(换音色)· generate_bgm(配乐)· translate_subtitles(字幕翻译)。均收费——generate_tts 是成片前必做且收费的配音步(不像 compose 免费);换音色/配乐/字幕翻译同样收费。 |
| Voice cloning声音克隆 | clone_voice (clone a voice from an authorized audio sample — billed per voice, auto-refunded on failure) · list_voices · delete_voice · set_character_voice (bind a cloned voice to a character; generate_tts then speaks in it). ⚠️ The sample must be a consented/licensed voice.clone_voice(从已授权音频样本克隆音色 — 按平台价每音色计费,失败自动退款)· list_voices · delete_voice · set_character_voice(把克隆音色绑到角色;之后 generate_tts 用它配音)。⚠️ 样本必须是本人/持权人同意授权的声音。 |
| Edit / cut视频编辑/剪辑 | get_edit_capabilities · quote/edit_video_shot (in-place edit + segment replace) · quote/regenerate_shot_video · split_shot · trim_shot · rerender_episode. edit_video_shot / regenerate_shot_video are quoted video spends; split_shot / trim_shot / rerender_episode are free (ffmpeg).get_edit_capabilities · quote/edit_video_shot(就地编辑+区间替换)· quote/regenerate_shot_video(单镜重生)· split_shot · trim_shot · rerender_episode(成片重拼)。edit_video_shot/regenerate_shot_video 有报价、出视频收费;split_shot/trim_shot/rerender_episode 免费(ffmpeg)。 |
| Refine assets资产精修 | update_character · delete_character · update_scene · delete_scene · generate_character_sheet (3-view) · generate_prop_sheet. update/delete are free; the two sheets are metered (image).update_character · delete_character · update_scene · delete_scene · generate_character_sheet(三视图)· generate_prop_sheet(道具设定图)。改/删免费;两个 sheet 收费(出图)。 |
| Drama-level assets剧目级资产 | Prop library (drama props — not the ad product library): get_props / create_prop / update_prop / delete_prop / mark_signature_prop / generate_prop_sheet. Read back generated shared assets: get_color_scripts / get_motion_templates (pair with generate_color_script / generate_motion_templates). CRUD & reads are free; only sheet / AI generation is metered.道具库(剧目道具,≠广告商品库):get_props/create_prop/update_prop/delete_prop/mark_signature_prop(招牌道具)/generate_prop_sheet。读回已生成的剧目共享资产:get_color_scripts/get_motion_templates(配 generate_color_script/generate_motion_templates 生成)。增删改/读取免费;仅出图/AI 生成收费。 |
| Music video (project_type=mv)MV 专属 | set_mv_lyrics → generate_mv_story → generate_mv_script · get_mv — MV skips the standard rewrite and uses this lyrics→story→script flow, then the normal extract→storyboards→… pipeline. set_mv_lyrics / get_mv are free; generate_mv_story / generate_mv_script are metered (LLM text).set_mv_lyrics → generate_mv_story → generate_mv_script · get_mv —— MV 跳过标准改写,走 歌词→故事→剧本,再接标准 提取→分镜→… 产线。set_mv_lyrics/get_mv 免费;generate_mv_story/generate_mv_script 收费(LLM 文本)。 |
| Continuity连续性/场景组 | chain_frames (frames inherit prev shot's last frame) · get_scene_group_plan · generate_scene_groups · render_multi_aspect (re-render vertical/landscape/square). Watch out: generate_scene_groups is a large video spend (batch group videos); chain_frames is metered when a shot pair needs a re-rendered frame; get_scene_group_plan and render_multi_aspect are free (ffmpeg).chain_frames(首帧承接上镜尾帧)· get_scene_group_plan · generate_scene_groups(场景组)· render_multi_aspect(多画幅重渲)。注意:generate_scene_groups 是大额出视频(批量分组视频);chain_frames 在镜对需重渲首帧时收费;get_scene_group_plan 与 render_multi_aspect 免费(ffmpeg)。 |
| Polish口型/海报/音效 | lipsync_shot · lipsync_episode · get_lipsync_status · generate_episode_poster · generate_drama_poster · generate_cover · generate_sfx · generate_effects · generate_transitions. lipsync_* / posters / cover are metered (video / image); get_lipsync_status and generate_sfx / generate_effects / generate_transitions are free (local-library match, no vendor).lipsync_shot/lipsync_episode(口型)· get_lipsync_status · generate_episode_poster/generate_drama_poster/generate_cover(海报封面)· generate_sfx(音效)· generate_effects(特效)· generate_transitions(转场)。lipsync_*/海报/封面 收费(出视频/图);get_lipsync_status 与 generate_sfx/generate_effects/generate_transitions 免费(本地库匹配,不调厂商)。 |
| Brand film / Ad品牌片/广告 | get_deliverables · generate_deliverables (brand-film deliverable tree) · add_product · list_products (ad product library). generate_deliverables / add_product / list_products are free; add_product only stores a catalog row (required for ads — the product is the subject), then generate_product_sheet (metered) makes its sheet, or the product drifts across shots.get_deliverables/generate_deliverables(品牌片交付物树)· add_product/list_products(广告商品库)。generate_deliverables/add_product/list_products 免费;add_product 仅建条目(广告必做——产品是广告主体),再用 generate_product_sheet(收费)出设定图,否则镜头产品漂移。 |
generate_frames makes one first frame per shot (the i2v identity anchor) and never makes last frames. generate_videos needs at least one first frame in the episode or it is blocked (400); any shot left without a first frame degrades to anchorless t2v (wasted spend, lost consistency), so give every shot a first frame. A last frame is optional and never produced by default — ask for one only to pin a shot's ending, e.g. a big camera move or a reveal (the engine then uses a first+last keyframe pair); subtle motion uses the first frame alone. To get one, generate it on-platform: generate_frames with frame_type=last_frame (batch, shots that already have a first frame) or generate_shot_frame (one shot). To fix a shot that came out wrong, redraw it with generate_shot_frame — that path carries the shot's character identity anchors, scene/prop references, style lock and frame audit. Generating the image in some other tool and pushing it in with upload_shot_frame bypasses all of it (faces, wardrobe and style drift); upload_shot_frame is for art the customer already owns. When a shot carries a reference video/image, first/last frames are dropped (vendor-exclusive), so most shots need no last frame.
帧规则 — 首帧必需、尾帧可选(不需要两张都生)。generate_frames 每镜只出一张首帧(i2v 身份锚),不产尾帧。generate_videos 要求整集至少一张首帧,否则拦(400);任何缺首帧的镜会退化成无锚点 t2v(白花钱、丢一致性),所以最好每镜都有首帧。尾帧可选、默认不出 — 只在想固定某镜结尾画面(如大运镜/揭示镜)时才要(引擎随即启用首+尾双关键帧);细微运动只用首帧。要尾帧就让平台生成:generate_frames 传 frame_type=last_frame(整集批量,只给已有首帧的镜)或 generate_shot_frame(单镜)。某一镜画错了要修,用 generate_shot_frame 重画 —— 这条路带着该镜的角色身份锚、场景/道具参考、画风锁与帧审计;拿别的工具出图再用 upload_shot_frame 贴进来会绕开这一整套(人脸/服装/画风会漂),upload_shot_frame 只用于客户自有素材。镜头带参考视频/图时,首/尾帧会被剥离(厂商互斥),故多数镜无需尾帧。Every MCP tool maps 1:1 to a REST endpoint under /v1/produce/* (same names, same params). The REST reference below covers authentication and the core flow; the tools above are the full surface.每个 MCP 工具与 /v1/produce/* 下的一个 REST 端点一一对应(同名同参)。下面 REST 章节讲鉴权与主干流程;上表即完整工具面。
Agent skill & disciplinesAI agent 操作 Skill 与纪律
A drop-in operating skill for any AI agent driving this pipeline — the ordered workflow, ten hard disciplines, and the one failure decision. It keeps an agent on the full pipeline, inside budget, compliant, and correct when a shot fails. 给任何驱动本产线的 AI agent 的一份即插即用操作 Skill — 完整工作流顺序、十条硬纪律、失败时的唯一决策。让 agent 照产线走、不超支、不违规、镜头失败时判得对。
SKILL.md shipped inside @starreel/mcp; (2) any other platform (Coze / Dify / GPTs / your own agent) — paste the block below into the system prompt; (3) it is this page's Billing + Troubleshooting contract, condensed.
三种加载方式:(1)支持 Skill 的 MCP 客户端会自动读取 @starreel/mcp 包内的 SKILL.md;(2)其他任意平台(Coze / Dify / GPTs / 自研 agent)—把下方文本块整段贴进 system prompt;(3)它就是本页「计费 + 常见问题处理」契约的浓缩。The ten disciplines十条纪律
- Prepaid, never overdraft.先充值,永不欠费。 On
402 insufficient_credits, stop and ask the user to recharge — never loop-retry a 402; it can't succeed.遇402 insufficient_credits立即停并提示充值 — 绝不循环重试 402,它不可能成功。 - Quote before you spend; the quote is the charge.先报价再花钱;报价即扣费。 Big-ticket stages (portraits / storyboards / frames / videos / scene-images) are
quote_*thengenerate_*— show the quote first. Other AI-generation steps (TTS, posters, sheets, style locks …) have no quote but still bill by usage. Show the user before any spend; don't auto-approve large ones.大额阶段(定妆图/分镜/首帧/视频/场景图)是quote_*后generate_*——先报价。其余 AI 生成步(TTS、海报、三视图、风格锁…)无报价但按用量照样收费。任何花钱前先告知用户;不替用户默认同意大额。 retryabledecides retry-vs-change.retryable一锤定音:重试还是改内容。false(moderation / copyright / quota / overdue) → change content or stop;true(KYC-queue / rate-limit / transient) → back off, retry. Never blind-retry.false(审核/版权/配额/欠费)→ 改内容或停;true(KYC 排队/限流/偶发)→ 退避后重试。绝不盲目重试。- Content must be compliant.内容必须合规。 No copyrighted characters, trademarks, real-person likenesses, or sensitive content. On rejection, rewrite toward generic, original imagery — don't fight the gate.不生成版权角色、商标、真人特征或敏感内容。命中拒收就改成通用原创形象 — 不硬刚审核门。
- Voice cloning needs consent.声音克隆须授权。 Only clone a sample the user is authorized to use (own voice or rights-holder consent). Never clone a third party's voice without permission.只克隆用户有权使用的样本(本人或持权人同意)。绝不未经授权克隆第三方声音。
- Follow the order; don't skip.照顺序走,不跳步。 Lock character portraits and sheets and frames before video — portraits alone leave characters drifting (sheets are the shot consistency anchor); no first frame degrades to anchorless t2v. Both waste money.出视频前先锁定妆图和设定图和首帧——只出定妆图人物会漂(设定图才是镜头一致性根锚);无首帧退化无锚点 t2v。都白花钱。
- Poll, don't block or hammer.轮询,别阻塞也别打爆。 Long steps are async; poll
get_pipeline_status/get_jobs/get_storyboardswith backoff. Stable counts = done.长步骤异步;带退避轮询get_pipeline_status/get_jobs/get_storyboards。数量稳定=完成。 - Idempotency — don't double-charge.幂等 — 不重复扣费。 A
quote_idis one-time (~15 min). Nevergenerate_*the same intent twice; read current state before regenerating.quote_id一次性(约 15 分钟)。同一意图绝不generate_*两次;重生前先读现状。 - Stay in your tenant.只碰自己的资源。 Someone else's id returns
404by design (probes never leak existence). Don't guess ids.别人的 id 一律404(探测不泄漏存在性)。别猜 id。 - Be transparent; keep secrets safe.对用户透明;守好密钥。 Report the quote, the failure reason, and actual spend — never fake success. Keep the API key in env / secrets, never in code or logs.如实呈现报价、失败原因、实际花费 — 绝不伪造成功。API key 放环境变量/密钥管理,绝不进代码或日志。
- Content is the user's, not yours.内容属于用户,不是你编的。 Never invent character names, titles, or dialogue — drive the pipeline from the user's script and choices.绝不自行编造角色名、剧名或台词 — 一切以用户的剧本与选择驱动产线。
Drop-in skill — copy into any agent's system prompt可整段复制 — 贴进任意 agent 的 system prompt
You are an agent driving StarReel, a PREPAID AI short-drama pipeline. You turn a
raw script into a downloadable episode via StarReel tools/endpoints.
PIPELINE (full, never skip):
create_drama → set_script(raw) → rewrite_script → extract_assets →
generate_portraits_and_sheets → storyboards → frames → videos →
generate_tts → compose_episode → final cut. Always generate frames BEFORE
videos. project_type = drama/ad/mv/brand_film (call list_project_options first).
TEN DISCIPLINES:
1. Prepaid, never overdraft. On 402 insufficient_credits, STOP and ask the user
to recharge. Never loop-retry a 402.
2. Quote before you spend; the quote is the charge. Big-ticket stages
(portraits/storyboards/frames/videos/scene-images) are quote_* then generate_*;
other AI steps (TTS/posters/sheets/style locks) have no quote but still bill.
Show the user before any spend; don't auto-approve large ones.
3. retryable decides retry-vs-change. false (moderation/copyright/quota/overdue)
→ change content or stop. true (KYC/rate-limit/transient) → back off, retry.
Never blind-retry.
4. Content must be compliant. No copyrighted characters, trademarks, real-person
likenesses, or sensitive content. On rejection, rewrite toward generic
original imagery; do not fight the gate.
5. Voice cloning needs consent. Only clone a sample the user is authorized to
use. Never clone a third party's voice without permission.
6. Follow the order; do not skip. Lock portraits and frames before video, or
video degrades to anchorless t2v (wasted money).
7. Poll, do not block or hammer. Long steps are async; poll get_pipeline_status
/ get_jobs / get_storyboards with backoff. Stable counts = done.
8. Idempotency. A quote_id is one-time (~15 min). Never double-generate the same
intent. Read current state before regenerating.
9. Stay in your tenant. Others' ids return 404 by design. Do not guess ids.
10. Be transparent; keep secrets safe. Report quote, failure reason, and actual
spend; never fake success. Keep the API key in env, never in code or logs.
ON FAILURE: read message / fail_reason / retryable.
moderation | identity | copyright → change content;
overdue | token → not self-healable (tell user / wait);
network | timeout | transient → retry. Failed spends are auto-refunded.
Docs: https://api.shortreelai.com/docs/mcpThese disciplines apply to REST integrations too — the same billing, moderation, and tenancy rules hold on /v1/produce/*.这些纪律同样适用于 REST 接入 — /v1/produce/* 上的计费、审核、租户规则完全一致。
Path B · REST API路径B · REST API
Plain HTTPS from any language. Every request carries the bearer token from Authentication. Switch the code samples with the curl / Python / Node.js selector at the top right. 任意语言的普通 HTTPS。每个请求带 鉴权换来的令牌。用右上角 curl / Python / Node.js 切换示例语言。
Base URL & response format基址与响应格式
- Base:
https://api.shortreelai.com基址:https://api.shortreelai.com - Every response is wrapped as
{ "code": 0, "data": {…} }; a non-zerocodeplus HTTP 4xx/5xx means error.响应统一包成{ "code": 0, "data": {…} };code非 0 且 HTTP 4xx/5xx 即错误。 - Auth helper (
token()/auth()) is the one from Authentication — reused in every example below.下面示例里的token()/auth()就是 鉴权那节的助手,全程复用。
Account账户
# identity
curl -H "authorization: Bearer $TOKEN" \
https://api.shortreelai.com/v1/me
# plan + spendable balance
curl -H "authorization: Bearer $TOKEN" \
https://api.shortreelai.com/v1/entitlement
# 200 -> { "code":0, "data":{ "allowed":true, "plan":"pro",
# "spendable":42000, "credits_balance":42000 } }me = requests.get(f"{BASE}/v1/me", headers=auth()).json()["data"]
ent = requests.get(f"{BASE}/v1/entitlement", headers=auth()).json()["data"]
print(me["email"], "balance:", ent["spendable"])const me = await (await fetch(BASE + "/v1/me", { headers: await auth() })).json();
const ent = await (await fetch(BASE + "/v1/entitlement", { headers: await auth() })).json();
console.log(me.data.email, "balance:", ent.data.spendable);Pipeline endpoints产线端点
All under /v1/produce/*, need produce scope. Spending stages follow one pattern: quote → confirm → poll. The quote returns a quote_id and the estimated points; show the user, then pass the quote_id to the matching generate call. Long stages run in the background.
全在 /v1/produce/* 下,需 produce scope。花钱阶段一个套路:报价 → 确认 → 轮询。报价返回 quote_id 和预估点数;给用户看,再把 quote_id 传给对应的 generate。长阶段后台异步。
| Endpoint端点 | Purpose用途 |
|---|---|
POST /v1/produce/dramas | Create drama (+episodes) → episode_ids. Free.建剧(+集)→ episode_ids。免费。 |
PUT /v1/produce/episodes/:id/script | Set script. Free.灌本。免费。 |
GET /v1/produce/episodes/:id/storyboards | Read shots (+ frame/video readiness). Free.读分镜(+帧/视频就绪)。免费。 |
POST /v1/produce/episodes/:id/storyboards/quote · /generate | Break script into storyboards.拆镜。 |
POST /v1/produce/episodes/:id/frames/quote · /generate | First frame per shot.每镜首帧。 |
POST /v1/produce/episodes/:id/videos/quote · /generate | Videos for the episode (quote == charge).整集视频(报价==扣费)。 |
POST /v1/produce/episodes/:id/compose | Merge into final cut. Free.终拼成片。免费。 |
GET /v1/produce/episodes/:id/final-cut | Status + download link when done.状态+完成时的下载链接。 |
Every response is wrapped as { "code": 0, "data": {…} }.响应统一包成 { "code": 0, "data": {…} }。
Quote → confirm → poll报价 → 确认 → 轮询
The video stage, shown three ways. Frames and storyboards work identically — just change the path segment. 以视频阶段为例(三种语言)。帧和分镜用法一样 — 改路径段即可。
# 1) quote — returns estimated_points + quote_id
Q=$(curl -s -X POST https://api.shortreelai.com/v1/produce/episodes/250/videos/quote \
-H "authorization: Bearer $TOKEN")
echo "$Q" # { "data": { "estimated_points": 1059, "quote_id": "q_..." } }
# 2) show the user the points, then confirm with the quote_id
QID=$(echo "$Q" | jq -r .data.quote_id)
curl -s -X POST https://api.shortreelai.com/v1/produce/episodes/250/videos/generate \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d "{"quote_id":"$QID"}" # -> { "data": { "status": "generating" } }
# 3) poll until every shot has a video_url
curl -s -H "authorization: Bearer $TOKEN" \
https://api.shortreelai.com/v1/produce/episodes/250/storyboardsdef stage(ep, name, poll_field=None):
q = requests.post(f"{BASE}/v1/produce/episodes/{ep}/{name}/quote", headers=auth()).json()["data"]
print(f"{name}: {q['estimated_points']} credits") # show the user, get their OK
requests.post(f"{BASE}/v1/produce/episodes/{ep}/{name}/generate",
headers=auth(), json={"quote_id": q["quote_id"]})
while poll_field: # poll storyboards until ready
sbs = requests.get(f"{BASE}/v1/produce/episodes/{ep}/storyboards", headers=auth()).json()["data"]
if sbs and all(s.get(poll_field) for s in sbs): break
time.sleep(10)
stage(250, "frames", poll_field="first_frame_image")
stage(250, "videos", poll_field="video_url")async function stage(ep, name, pollField) {
const q = (await (await fetch(`${BASE}/v1/produce/episodes/${ep}/${name}/quote`,
{ method: "POST", headers: await auth() })).json()).data;
console.log(`${name}: ${q.estimated_points} credits`); // show the user, get their OK
await fetch(`${BASE}/v1/produce/episodes/${ep}/${name}/generate`,
{ method: "POST", headers: { ...(await auth()), "content-type": "application/json" },
body: JSON.stringify({ quote_id: q.quote_id }) });
while (pollField) {
const sbs = (await (await fetch(`${BASE}/v1/produce/episodes/${ep}/storyboards`,
{ headers: await auth() })).json()).data;
if (sbs.length && sbs.every(s => s[pollField])) break;
await new Promise(r => setTimeout(r, 10000));
}
}
await stage(250, "frames", "first_frame_image");
await stage(250, "videos", "video_url");Full run — script to download link整条跑通 — 从剧本到下载链接
# create -> set script -> storyboards -> frames -> videos -> compose -> download
# (each stage: quote, then generate with the quote_id; poll between stages)
# see the Python / Node tabs for a runnable end-to-end script.d = requests.post(f"{BASE}/v1/produce/dramas", headers=auth(),
json={"title": "My Drama", "total_episodes": 1}).json()["data"]
ep = d["episodes"][0]["episode_id"]
requests.put(f"{BASE}/v1/produce/episodes/{ep}/script", headers=auth(),
json={"script_content": my_script})
stage(ep, "storyboards", poll_field=None) # background; poll get_storyboards for shots
# ... wait for storyboards, then:
stage(ep, "frames", poll_field="first_frame_image")
stage(ep, "videos", poll_field="video_url")
requests.post(f"{BASE}/v1/produce/episodes/{ep}/compose", headers=auth())
while True:
fc = requests.get(f"{BASE}/v1/produce/episodes/{ep}/final-cut", headers=auth()).json()["data"]
if fc.get("download_url"): print("done:", fc["download_url"]); break
time.sleep(8)const d = (await (await fetch(`${BASE}/v1/produce/dramas`, { method: "POST",
headers: { ...(await auth()), "content-type": "application/json" },
body: JSON.stringify({ title: "My Drama", total_episodes: 1 }) })).json()).data;
const ep = d.episodes[0].episode_id;
await fetch(`${BASE}/v1/produce/episodes/${ep}/script`, { method: "PUT",
headers: { ...(await auth()), "content-type": "application/json" },
body: JSON.stringify({ script_content: myScript }) });
await stage(ep, "storyboards"); // then poll get_storyboards
await stage(ep, "frames", "first_frame_image");
await stage(ep, "videos", "video_url");
await fetch(`${BASE}/v1/produce/episodes/${ep}/compose`, { method: "POST", headers: await auth() });
let fc;
do { await new Promise(r => setTimeout(r, 8000));
fc = (await (await fetch(`${BASE}/v1/produce/episodes/${ep}/final-cut`,
{ headers: await auth() })).json()).data;
} while (!fc.download_url);
console.log("done:", fc.download_url);Upload your own images (portraits, frames, scenes, props)上传自有图片(定妆图/首帧/场景/道具)
Bring your own reference art instead of AI-generating it. The headline case is character portraits: an uploaded portrait becomes that character's identity anchor (source user_upload, priority over AI — later AI regens won't overwrite it), auto-invalidates & rebuilds derived assets (character sheet, hair/body refs) and registers a face-lock. Shot frames / scene images / prop sheets work the same way.
用你自己的参考图,而不是 AI 生成。最典型是角色定妆图:上传的定妆图成为该角色的身份锚(来源 user_upload,优先级高于 AI — 之后 AI 重生默认不覆盖),并自动失效重建派生资产(三视图设定图、发型/身材参考)、登记人脸锁。首帧/场景图/道具设定图同理。
set_character_portrait({character_id, file_path}) uploads a local file to COS and registers it in one step (or pass image_url for an already-hosted image). Likewise upload_shot_frame / upload_scene_image / upload_prop_sheet. All free.
MCP — 一次调用:set_character_portrait({character_id, file_path}) 把本地文件传 COS 并登记,一步搞定(或传 image_url 用已托管的图)。upload_shot_frame / upload_scene_image / upload_prop_sheet 同理。均免费。REST — three steps: presign → PUT the bytes straight to COS → register.REST — 三步:拿预签名 → PUT 字节直传 COS → 登记。
# 1) presign — 拿直传 URL(图片字节不过业务服务器)
curl -X POST https://api.shortreelai.com/v1/produce/upload-url \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"filename":"portrait.jpg","content_type":"image/jpeg","size":204800,"kind":"image"}'
# 200 -> { "code":0, "data":{ "put_url":"https://cos...", "public_url":"https://cos.../portrait.jpg",
# "headers":{"content-type":"image/jpeg"} } }
# 2) 用 put_url PUT 文件字节(带 data.headers 里要求的头)
curl -X PUT "$PUT_URL" -H 'content-type: image/jpeg' --data-binary @portrait.jpg
# 3) 用 public_url 登记为该角色定妆图(身份锚)
curl -X POST https://api.shortreelai.com/v1/produce/characters/42/portrait \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"image_url":"https://cos.../portrait.jpg"}'pre = requests.post(f"{BASE}/v1/produce/upload-url", headers=auth(), json={
"filename": "portrait.jpg", "content_type": "image/jpeg",
"size": 204800, "kind": "image"}).json()["data"]
requests.put(pre["put_url"], data=open("portrait.jpg", "rb").read(),
headers=pre.get("headers") or {"content-type": "image/jpeg"})
requests.post(f"{BASE}/v1/produce/characters/42/portrait", headers=auth(),
json={"image_url": pre["public_url"]})const pre = (await (await fetch(BASE + "/v1/produce/upload-url", {
method: "POST", headers: { ...(await auth()), "content-type": "application/json" },
body: JSON.stringify({ filename: "portrait.jpg", content_type: "image/jpeg",
size: 204800, kind: "image" }) })).json()).data;
await fetch(pre.put_url, { method: "PUT",
headers: pre.headers || { "content-type": "image/jpeg" }, body: fileBytes });
await fetch(BASE + "/v1/produce/characters/42/portrait", {
method: "POST", headers: { ...(await auth()), "content-type": "application/json" },
body: JSON.stringify({ image_url: pre.public_url }) });The same upload-url presign works for any image / video / audio; register with the matching endpoint (/storyboards/:id/frame, /scenes/:id/image, /props/:id/sheet). Uploads are free — you only pay when you later generate from them.同一个 upload-url 预签名适用于任意图片/视频/音频,再用对应端点登记(/storyboards/:id/frame、/scenes/:id/image、/props/:id/sheet)。上传免费 — 只有之后据它生成才计费。
Troubleshooting常见问题处理
Every failure surfaces as a human-readable message (the MCP client throws Error(message); REST returns { code, message } or, on the metered /v1/ai/* layer, { error: { message, type, needed?, retryable? } }). The message is written for your agent to act on — read it, don't blindly retry. Failed spends are auto-refunded (pre-hold → refund on failure), so you never need to compensate manually.所有失败都带一段人类可读的 message(MCP 客户端抛 Error(message);REST 返回 { code, message },计费层 /v1/ai/* 返回 { error: { message, type, needed?, retryable? } })。这段 message 是给 agent 行动用的 —— 照它做,别盲目重试。失败的扣费一律自动退款(预扣→失败退款),不用手动补偿。
★ Shot images / videos: rejected vs. failed — how to tell & what to do★ 镜头图片 / 视频:拒收 vs 失败 —— 怎么判、怎么办
Generation is async: call generate_frames / generate_videos, then poll get_storyboards. Each shot now carries structured status so you don't parse text: frame_status / video_status (ready/pending/authorizing/rejected/failed/none), fail_reason (the enum in the table below), retryable (the one flag that decides retry-vs-change), and fail_hint (human message). Retrying a rejection is useless; retrying a transient failure is correct.生成是异步的:调 generate_frames / generate_videos 后轮询 get_storyboards。每镜现在直接带结构化状态,不用解析文案:frame_status / video_status(ready/pending/authorizing/rejected/failed/none)、fail_reason(下表的枚举)、retryable(一锤定音:该重试还是该改)、fail_hint(人读文案)。拒收去重试是白费;偶发失败去重试才对。
| What you see (message)现象(真实文案) | Cause根因 | Agent actionagent 应对 |
|---|---|---|
「…未通过厂商内容审核(判定为含敏感信息)…」"…failed content moderation (sensitive)…" retryable:false | 画面命中敏感内容(终态)Frame hit sensitive content | ❌ 别重试 → 改画面内容/换参考图,重生该帧Don't retry → change the picture / swap the reference image, regenerate the frame |
| 「…未通过厂商人脸一致性核验…」"…failed face-consistency…" | 定妆图与已授权人物不是同一人Portrait ≠ authorized person | 换定妆图 / 确认同一人后重生Swap the portrait / confirm same person |
| 「…文字描述被判定为敏感(判的是文字,不是画面)…」"…text judged sensitive (the text, not the picture)…" | prompt 文本敏感(任务未创建,未扣费)Prompt text is sensitive | 改 prompt 措辞(不是换图),重试Reword the prompt (not the image), retry |
| 「…判定可能涉及版权或敏感形象,已自动拦截并退还本次积分…改为通用/原创形象…」"…possible copyright/sensitive likeness, auto-blocked & refunded…use generic/original…" | 版权角色/商标/真人特征Copyright / trademark / real-person | 改成通用原创形象;避免可识别的版权角色/商标/真人Use generic original imagery; avoid recognizable IP/trademark/real person |
「人物帧正在完成人脸授权(KYC),约 1 分钟后重试即可」"face frame finishing KYC, retry in ~1 min" 503 retryable:true | 含人脸帧走 KYC 授权排队(不是拒)Face frame queuing for KYC (not a rejection) | ✅ 等 ~1 分钟后重试Wait ~1 min, retry |
「上游账户欠费/余额不足,厂商拒绝生成(与 prompt 无关)」"upstream account overdue, vendor refused (unrelated to prompt)" 502 | 火山 Ark 厂商账户欠费(平台级)Vendor (Ark) account overdue | 给 Ark 账户充值;不改 prompt。★ 别把欠费当敏感去改画面Recharge the Ark account; don't touch the prompt. ★ Don't mistake overdue for sensitive |
「…平台侧厂商素材库配额已满…换图或重试都不会改变结果…」"…vendor asset-store quota full…retry won't help…" retryable:false | 平台配额满(基建)Platform quota exhausted | 重试无效,联系运营Retry is useless, contact ops |
BestOfN 全失败 / frame-promotion-rejectedBestOfN all-failed / quality gate | 偶发/质量闸未过Transient / quality gate | ✅ 可直接重试(regenerate_shot_video / 重出帧)Retry (regenerate) |
The one signal that decides it: the retryable flag. true (KYC-queuing, rate-limit) → back off and retry; false (moderation, copyright, quota) → change content / swap image, retrying will never work.一锤定音的信号:retryable 字段。true(KYC 排队、限流)→ 退避后重试;false(审核、版权、配额)→ 改内容/换图,重试永远无效。
Billing — 402 vs 403计费 —— 402 与 403
402 insufficient_credits(withneeded) — this call costs more than the balance. Tell the user to recharge; do not loop-retry.(带needed)—— 本次点数不够。提示用户充值;绝不循环重试。403 not_entitled(reason:no_credits/status_suspended) — zero balance or suspended account, blocked at the gate before any spend.(reason:no_credits/status_suspended)—— 零余额或账户封禁,在扣费前被入口拦。- Prepaid, no overdraft: post-paid text settling short drains the balance to zero and blocks the account until recharge — never a negative balance.先充值不欠费:后付文本结算不足会把余额扣尽到零并停用账户直到充值 —— 绝不出现负余额。
Vendor / edit 400 / auth / async厂商 / 区间替换 400 / 鉴权 / 异步
- Segment replace:
start_sec/end_secmust be non-negative integers,start < end, within the source duration; source must be ≥ the vendor minimum.VIDEO_EDIT_MODE off→ 403.区间替换:start_sec/end_sec须非负整数、start < end、不超源片时长;源片须 ≥ 厂商下限。编辑模式未开 → 403。 - Vendor: timeout →
504, unreachable →502. Rate-limited →429withRetry-After.厂商:超时 →504,不可达 →502。限流 →429带Retry-After。 - Auth:
invalid api key401 → create a new key (the MCP client auto-re-exchanges the token once).scope insufficient403 → use a key withproduce/readscope.鉴权:invalid api key401 → 重建 Key(MCP 客户端会自动重换一次令牌)。scope 不足403 → 换带produce/readscope 的 Key。 - Async: long steps return
status:generatingimmediately — pollget_storyboards/get_jobs/get_pipeline_status; stable counts = done; stuck → readget_jobserrorMsg. Gateway hard timeout 180s → 504.异步:长步骤立即返status:generating—— 轮询get_storyboards/get_jobs/get_pipeline_status;数量稳定=完成;卡住→读get_jobs的errorMsg。网关硬超时 180s → 504。
Facade 4xx you'll hit most (order matters)最常撞的门面 4xx(顺序很重要)
- Follow the order:
set_script(raw) →rewrite_script→extract_assets→ storyboards → frames → videos. Skipping gives "先 set_script / 本集无剧本 / 本剧尚无角色".照顺序走:set_script(原始)→rewrite_script→extract_assets→ 分镜 → 帧 → 视频。跳步会得到「先 set_script / 本集无剧本 / 本剧尚无角色」。 - "本集 N 镜均无首帧;先 generate_frames,否则视频会退化成无锚点 t2v" — always generate frames before videos.「本集 N 镜均无首帧;先 generate_frames…」—— 出视频前必先出帧,否则退化成无锚点 t2v(白花钱)。
invalid or expired quote_id— aquote_idis one-time and expires in 15 min. Re-call the matching*/quotefor a fresh one.invalid or expired quote_id——quote_id一次性、15 分钟过期。重调对应*/quote拿新的。404 not foundon someone else's resource is intentional (cross-tenant probes 404, never leak existence).别人的资源404是故意的(跨租户探测一律 404,不泄漏资源是否存在)。
Agent handling principlesAI agent 通用处理原则
- Three action classes: moderation / identity / copyright rejection → change content or swap image (retry never works); vendor overdue / token → not self-healable (tell user / wait); network / timeout / BestOfN transient → retry.三类动作:审核/身份/版权拒 → 改内容或换图(重试无效);厂商欠费/token → 不可自愈(提示用户/等待);网络/超时/BestOfN 偶发 → 可重试。
402= stop and prompt to recharge; never loop-retry. Failed spends are already refunded.402= 停并提示充值;绝不循环重试。失败扣费已自动退款。- Poll, don't block. Read the
message/errorMsgto decide the action — it's the authoritative "what to do".轮询,别阻塞。读message/errorMsg决定动作 —— 它就是权威的"该怎么办"。
Status codes状态码
| Code码 | Meaning & what to do含义与处理 |
|---|---|
401 | Key invalid/revoked (indistinguishable by design), or token expired → re-exchange.Key 无效/已吊销(响应一致),或令牌过期 → 重新交换。 |
402 | Insufficient balance — recharge. Response includes needed.余额不足 — 请充值。响应带 needed。 |
403 | Scope insufficient (code 4031) → use a key with the right scope.scope 不足(code 4031)→ 换带对应 scope 的 Key。 |
409 | Active key limit reached (5) → revoke an unused one.活跃 Key 达上限(5)→ 吊销不用的。 |
429 | Rate-limited (token exchange 30/min/IP) → cache your token.限流(交换 30/分/IP)→ 缓存令牌。 |
Security安全
- Keys are stored hashed — a lost plaintext can't be recovered, so rotate (revoke + create).Key 只存哈希 — 丢失明文无法找回,丢了就吊销重发。
- Each key is independently revocable and audited (last-used time visible in Settings).每把 Key 独立吊销、独立审计(设置页可见最近使用)。
- Tokens expire in 15 minutes; revoking a key never affects your web login.令牌 15 分钟过期;吊销 Key 不影响网页登录。
- Keep keys in environment variables or a secrets manager — never commit them.Key 放环境变量或密钥管理,别提交进仓库。