关于 aituber-api
aituber-api 是用于生成 AI 视频的 API 技能,可从脚本、创意、网页或 PDF 制作旁白视频,并支持导出和发布到已连接的社交平台。
主要功能
- 01根据脚本或创意生成视频
- 02将网页和 PDF 转为视频
- 03选择旁白音色和视觉风格
- 04导出 MP4 视频
- 05发布到已连接的社交平台
适用场景
- 01将脚本制作成旁白视频
- 02把文章或 PDF 制成视频
- 03导出已完成的视频
- 04将视频发布到社交平台
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aituberapp/ ai-video-skill --skill aituber-api安装后在 Claude Code 中输入/aituber-api确认已加载。
附带文件README.mdLICENSE
详细介绍
AITuber API
根据脚本或创意创建 AI 视频。从 15 秒的 Shorts 到 20 分钟的长视频内容。此 API 可处理语音旁白(支持 1,300 多种声音和任意语言)、AI 生成的视觉内容、与语音同步的字幕、MP4 导出,以及发布到 YouTube、TikTok、Instagram、Facebook、Threads 和 X。
基础 URL: https://app.aituber.app/api/v1
OpenAPI 规范: https://app.aituber.app/api/v1/openapi.json
API 文档: https://aituber.app/api
提示: 以下端点参考和积分费用根据实时 API 定义生成,因此与当前 API 保持一致。如需交互式探索和查看响应架构,请使用 OpenAPI 规范或文档页面。
身份验证
除 GET /voices 外,所有端点都需要 Bearer 令牌。请在 AITuber 控制面板中创建 API 密钥:https://app.aituber.app/dashboard/api-keys。密钥以 ak_ 开头。
Authorization: Bearer <AITUBER_API_KEY>
将密钥存储在 AITUBER_API_KEY 环境变量中。
完整工作流
AITuber 支持生成后常用的两种流程:
- 导出流程: 选择声音、生成视频、轮询状态、导出、下载
- 发布流程: 选择声音、生成视频、轮询状态、列出频道、发布、轮询发布状态
步骤 1:选择声音
curl "https://app.aituber.app/api/v1/voices?gender=male&accent=American"
无需身份验证。返回声音对象数组。生成视频时,使用 id 字段作为 voiceId,也可以省略 voiceId 以使用默认声音。
步骤 2:生成视频
根据脚本生成(由你撰写旁白):
curl -X POST "https://app.aituber.app/api/v1/videos/generate" \
-H "Authorization: Bearer $AITUBER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"script": "The human brain contains roughly 86 billion neurons. Every thought, memory, and emotion is the result of electrical signals racing through this incredible network.",
"voiceId": "VOICE_ID_FROM_STEP_1",
"imageStyleId": "cinematic",
"aspectRatio": "9:16"
}'
根据创意生成(由 AI 撰写脚本):
curl -X POST "https://app.aituber.app/api/v1/videos/generate" \
-H "Authorization: Bearer $AITUBER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"script": "5 mind-blowing facts about black holes",
"inputType": "idea",
"expectedDurationSeconds": 60
}'
返回 { "videoId": "uuid", "status": "pending" }。
视频类型(均使用同一端点):
- 不露脸旁白(图片) - 默认类型。使用带有 Ken Burns 动画的 AI 图片。只需发送脚本或创意。
- 不露脸旁白(视频片段) - AI 视频片段。设置
mediaType: "video"。 - 库存素材 - 与旁白匹配的真实库存素材。设置
mediaType: "stock"。 - 骨骼模板 - 病毒式传播的“如果……会怎样”X 光风格。设置
templateId: "skeleton"。模板会处理mediaType和风格。 - 角色模板 - 以角色为主线的故事。设置
templateId: "character"、inputType: "idea"。仅支持创意模式(AI 会撰写脚本,以保持角色一致性)。 - 文章或链接转视频 - 发送公开网页,而不是脚本。设置
inputType: "source"和source: { kind: "url", url: "https://..." }。制作视频期间,我们会抓取并读取页面,因此无需提供script。必须设置expectedDurationSeconds。 - PDF 转视频 - 发送 PDF,而不是脚本。先通过
POST /uploads上传文件(purpose: "document-source",仅支持 PDF,最大 25MB)以获取assetId,然后设置inputType: "source"和source: { kind: "document", assetId: "..." }。必须设置expectedDurationSeconds。
对于第 6 和第 7 种类型,source.mode 决定如何处理文本:summarize(默认)会在忠于原文的基础上撰写简短旁白;read-out 会逐字朗读文本,并将 expectedDurationSeconds 视为时长上限。添加 source.instructions 可引导生成方向,例如“重点关注费用部分”。如果你想自行阅读页面或文件,可将文本放入 script,并在知道标题时提供 source.title。
在脚本模式下控制画面时,可在方括号中添加说明:[A dark forest at night] The wind howled through the trees. 每个 [bracket] 都会告知 AI 该场景要展示的内容。
步骤 3:轮询完成状态
curl "https://app.aituber.app/api/v1/videos/VIDEO_ID" \
-H "Authorization: Bearer $AITUBER_API_KEY"
每隔 5-10 秒轮询一次。生成通常需要 1-3 分钟。等待 status 变为 completed(或 failed)。
步骤 4:导出为 MP4
curl -X POST "https://app.aituber.app/api/v1/exports" \
-H "Authorization: Bearer $AITUBER_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "videoId": "VIDEO_ID", "resolution": "1080p" }'
导出免费。需要有效的付费订阅。轮询 GET /videos/VIDEO_ID,并检查 exportStatus,直到其变为 completed(通常需要 30 秒到 5 分钟)。
步骤 5:下载 MP4
curl "https://app.aituber.app/api/v1/exports/download?videoId=VIDEO_ID" \
-H "Authorization: Bearer $AITUBER_API_KEY"
返回 { "url": "https://...", "videoId": "..." }。该 URL 是带签名的临时链接,2 分钟后过期。请立即下载。
步骤 6:发布到已连接的渠道
发布需要先在 AITuber 控制面板中连接渠道,并拥有启用了 Publish 功能的有效付费订阅。如果视频尚未导出,API 会自动开始导出(无需先调用 POST /exports)。
列出渠道:
curl "https://app.aituber.app/api/v1/channels" \
-H "Authorization: Bearer $AITUBER_API_KEY"
一次调用即可发布到 YouTube、TikTok、Instagram、Facebook、Threads 和 X:
curl -X POST "https://app.aituber.app/api/v1/publications" \
-H "Authorization: Bearer $AITUBER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"videoId": "VIDEO_ID",
"caption": "New short is live",
"shortCaption": "New short is live. What do you think?",
"publishNow": true,
"channels": [
{
"channelId": "YOUTUBE_CHANNEL_ID",
"title": "5 Mind-Blowing Facts",
"tags": ["facts", "science"],
"categoryId": "27"
},
{
"channelId": "TIKTOK_CHANNEL_ID",
"tiktokPrivacyStatus": "public",
"isAiGenerated": true
},
{
"channelId": "INSTAGRAM_CHANNEL_ID",
"instagramPlacement": "reels"
},
{ "channelId": "FACEBOOK_CHANNEL_ID" },
{ "channelId": "THREADS_CHANNEL_ID" },
{ "channelId": "X_CHANNEL_ID" }
]
}'
各平台的渠道设置:
- YouTube:
title、tags、categoryId、madeForKids - TikTok:
tiktokPrivacyStatus、allowDuet、allowStitch、isAiGenerated - Instagram:
instagramPlacement、shareToFeed - TikTok 和 X:
allowComment。其他平台均无法更改此设置。
轮询发布状态:
curl "https://app.aituber.app/api/v1/publications/PUBLICATION_ID" \
-H "Authorization: Bearer $AITUBER_API_KEY"
每隔 10-15 秒轮询一次,直到上传达到稳定状态,例如 published、scheduled 或 failed。
端点参考
GET /voices
返回可用于视频旁白的所有 AI 声音,按受欢迎程度排序。无需身份验证。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| gender | string | 否 | 按声音性别筛选。可选值:"male"、"female"、"neutral"。 |
| accent | string | 否 | 按口音筛选(不区分大小写)。例如:"American"、"British"、"Australian"、"Indian"。 |
| age | string | 否 | 按年龄段筛选。可选值:"young"、"middle_aged"、"old"。 |
| useCase | string | 否 | 按推荐用途筛选(不区分大小写)。例如:"narration"、"conversational"、"news"、"audiobook"、"social_media"。 |
| language | string | 否 | 筛选针对特定语言优化的声音(ISO 639-1 代码)。例如:"en"、"es"、"fr"、"hi"、"zh"。 |
| search | string | 否 | 按名称或描述搜索声音(不区分大小写)。例如:"roger"、"energetic"、"calm"。 |
GET /voices/cloned
返回你在 AITuber 控制面板中克隆的声音。
GET /avatars
返回所有可用于对话视频的虚拟形象:所有人均可使用的内置虚拟形象,以及你自己的角色。
GET /elements
返回已保存的元素:人物/角色、产品/道具和地点,以及内置元素。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| type | character | prop | location | 否 | 按元素类型筛选。不填则返回全部。 |
POST /elements
使用参考照片保存可重复使用的元素(人物/角色、产品/道具或地点)。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | string | 是 | 元素名称,用于生成 @handle。建议使用字母、数字、空格和连字符(例如 "Maya"、"Red Bottle")。 |
| type | character | prop | location | 是 | character = 人物或吉祥物(也可用作虚拟形象),prop = 物体或产品,location = 地点。 |
| description | string | 否 | 可选的背景说明(元素是什么、何时使用)。请勿描述外观;元素的外观以照片为准。 |
| imageUrl | string | 否 | 参考照片的公开 URL(JPEG、PNG 或 WebP,最大 25MB)。我们会下载并存储该照片。请使用此参数或 imageAssetId。 |
| imageAssetId | string (uuid) | 否 | 来自 POST /uploads 且用途为 element-image 的资源。请使用此参数或 imageUrl。 |
POST /uploads
将媒体文件添加到你的 AITuber 库,并返回可传递给其他端点的 assetId。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| purpose | background-video-library-upload | background-video-upload | clip-reference-image | clip-reference-video | clip-reference-audio | rebuild-still | document-source | element-image | visual-style-reference | ugc-demo | music | voice-sample | agent-attachment | 是 | 文件的用途。仅接受列出的用途;每种用途会开放特定端点(参见端点描述)。 |
| sourceUrl | string | 否 | 用于下载文件的公开 URL(仅限图像用途)。请使用此参数,或使用 contentType+fileSizeBytes,不要同时使用两者。 |
| contentType | image/jpeg | image/png | image/webp | video/mp4 | video/quicktime | video/webm | audio/mpeg | audio/wav | audio/mp4 | audio/x-m4a | audio/aac | audio/mp3 | audio/wave | audio/x-wav | audio/ogg | audio/webm | application/pdf | 否 | 直接上传时的文件类型。会返回一个 uploadUrl,用于 PUT 文件数据。必须与用途匹配(图像、视频、音频或文档)。 |
| fileSizeBytes | integer | 否 | 直接上传时的文件大小(字节)。最大值取决于用途(图像 25MB、视频 200MB、音频 50MB、文档 25MB)。 |
| durationSeconds | number | 否 | 视频(ugc-demo,1-180 秒)和音频(music,1-600 秒)上传时必填。片段或音轨的时长(秒)。用于确定片段时长。 |
| videoWidth | integer | 否 | 视频上传(ugc-demo)时的像素宽度。建议提供,以便正确构图演示视频。 |
| videoHeight | integer | 否 | 视频上传(ugc-demo)时的像素高度。建议提供,以便正确构图演示视频。 |
| fileName | string | 否 | 文件名,用于显示(document-source 会显示该名称,而不是 ID)。目录部分会被移除。 |
GET /ugc/reactions
返回人物对着镜头作出反应的短片,分为 system(内置库)和 custom(你生成的反应)。
POST /ugc/reactions
使用图像转视频 AI 生成角色对着镜头作出反应的短片。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| avatarImageUrl | string | 否 | 仅供 Dashboard 使用。公开调用方应改为传入 elementId;公开 API 中的 avatarImageUrl 必须是由 AITuber 托管的资源 URL。 |
| elementId | string (uuid) | 否 | 作出反应的角色元素。通过 GET /elements(类型为 character)获取 ID,或使用 POST /elements 创建元素。 |
| avatarId | string (uuid) | 否 | 旧版 avatar ID。建议使用 elementId。 |
| reactionPrompt | string | 否 | 直接控制反应,例如“震惊、瞪大双眼、向后倾身”。请提供此参数或 hookText。 |
| hookText | string | 否 | 角色作出反应的引子。AI 会将其转化为合适的表情。请提供此参数或 reactionPrompt。 |
| quality | good | premium | 否 | 生成质量。premium 费用更高,效果也更好。 |
GET /ugc/reactions/{id}
返回你生成的反应。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | string (uuid) | 是 | 来自 POST /ugc/reactions 的反应 ID。 |
POST /ugc/videos
生成一段完整的 UGC 风格钩子视频:人物反应片段上叠加钩子文案,也可选择在后面接上你的产品演示视频。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| hookText | string | 是 | 屏幕上显示的钩子文案(5-200 个字符)。 |
| reactionId | string (uuid) | 否 | 来自 GET /ugc/reactions 的反应片段。 |
| ugcVideoId | string (uuid) | 否 | Dashboard 中 reactionId 的别名。公开调用方使用 reactionId。 |
| demoVideoAssetId | string (uuid) | 否 | 可选的产品演示视频,通过 POST /uploads 上传(purpose ugc-demo)。在反应片段之后播放。 |
| demoVideoUrl | string | 否 | 仅供 Dashboard 使用。公开调用方应改为传入 demoVideoAssetId。 |
| demoDurationSeconds | number | 否 | 仅供 Dashboard 使用。设置 demoVideoUrl 时必填。 |
| demoVideoWidth | integer | 否 | 仅供 Dashboard 使用。 |
| demoVideoHeight | integer | 否 | 仅供 Dashboard 使用。 |
| hookTextPosition | top | center | bottom | 否 | 钩子文案的位置。 |
| aspectRatio | 9:16 | 16:9 | 1:1 | 否 | 视频尺寸。 |
| backgroundMusicId | string (uuid) | 否 | 仅供 Dashboard 使用。背景音乐曲目 ID。 |
| backgroundMusicVolume | number | 否 | 仅供 Dashboard 使用。背景音乐音量(0-100)。 |
| captionStyleId | string | 否 | 来自 GET /caption-styles 的字幕样式 ID。默认值:"tiktok"。 |
| title | string | 否 | 可选的视频标题。 |
POST /music
使用 AI 根据文本提示词生成原创歌曲。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| prompt | string | 是 | 描述歌曲的主题或风格,例如 "一首关于夏日公路旅行的欢快独立流行乐曲"。在自定义模式下,此项为可选背景信息;歌词取自 lyrics,风格取自 style。 |
| instrumental | boolean | 否 | 设为 true 可生成无人声、无歌词的曲目。 |
| customMode | boolean | 否 | 设为 true 可自行设置 style、title 和 lyrics,而不是让 AI 根据 prompt 决定。 |
| style | string | 否 | 仅限自定义模式:音乐风格,例如 "lo-fi hip hop、舒缓、爵士钢琴"。 |
| title | string | 否 | 仅限自定义模式:歌曲标题。 |
| lyrics | string | 否 | 仅限自定义模式:要演唱的确切歌词。instrumental 为 true 时会忽略此项。 |
GET /music
列出音乐库中的曲目,包括通过 POST /music 生成的歌曲,以及通过 POST /uploads 上传的音频(purpose music)。
GET /music/{id}
返回你生成的歌曲。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| id | string (uuid) | 是 | 来自 POST /music 的歌曲 ID。 |
POST /music-videos
制作音乐视频:将你的歌曲与 AI 视觉画面、同步字幕和可选的波形动画结合起来。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| musicId | string (uuid) | 否 | 来自 POST /music 的已完成歌曲。填写此项或 musicAssetId,不能同时填写。 |
| musicAssetId | string (uuid) | 否 | 通过 POST /uploads 上传的音轨(purpose music)。填写此项或 musicId,不能同时填写。 |
| visualMode | ai-images | ai-video | cover-image | 是 | ai-images(每隔几秒生成一张新的 AI 图片)、ai-video(生成 AI 短片)或 cover-image(整首歌曲使用同一张静态图片)。 |
| visualDirection | string | 否 | 可选的视觉画面艺术指导,例如“霓虹赛博朋克风格的夜间城市,氛围阴郁”。使用 @handle 提及已保存的元素(参见 GET /elements)以便复用,例如“屋顶上的 @Robo-Cat”。每当该元素出现在场景中,都会将其照片提供给图像模型,以确保其在每个场景中外观一致。对于 ai-images,每提及一个元素,每个场景都会产生一笔参考费用。 |
| imageStyleId | string | 否 | ai-images/ai-video 的图像风格。从 GET /image-styles 获取 ID。 |
| imageQuality | basic | good | premium | max | 否 | ai-images 的图像质量(质量越高,费用越高)。 |
| secondsPerImage | number | 否 | 对于 ai-images:每张图片显示的秒数。秒数越少,图片数量越多,消耗的积分也越多。 |
| videoQuality | basic | good | premium | max | 否 | ai-video 的短片质量(质量越高,费用越高)。 |
| coverImageAssetId | string (uuid) | 否 | 对于 cover-image 模式:通过 POST /uploads 上传的图片(purpose element-image)。该模式下必填。 |
| aspectRatio | 9:16 | 16:9 | 1:1 | 否 | 视频尺寸。 |
| captionsEnabled | boolean | 否 | 显示与歌词逐词同步的字幕。纯音乐音轨会自动关闭此项。 |
| captionStyleId | string | 否 | 来自 GET /caption-styles 的字幕样式 ID。 |
| captionPosition | top | center | bottom | 否 | 字幕在屏幕上的位置。 |
| showWaveform | boolean | 否 | 显示音频波形动画。 |
| musicTrimStartSeconds | number | 否 | 从歌曲的这一时间点开始播放视频(秒)。默认为歌曲开头。 |
| musicTrimEndSeconds | number | 否 | 在歌曲的这一时间点结束视频(秒)。默认为歌曲结尾。 |
POST /ideas
为特定细分领域或受众生成一系列具体的、具有病毒式传播风格的视频主题创意。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| prompt | string | 是 | 要进行头脑风暴的细分领域、受众或主题。例如:“为不露脸的 YouTube Shorts 频道创作太空知识”。 |
| language | string | 否 | 创意使用的语言(ISO 639-1 代码,例如 "en"、"es"、"hi")。默认值:"en"。 |
| count | number | 否 | 要生成的创意数量(5-15)。默认值:10。 |
| source | tool_page | inline | 否 | 请求的来源,仅用于分析。供仪表板使用;可以省略。 |
| templateId | string | 否 | 请求所使用的创作模板,仅用于分析。供仪表板使用;可以省略。 |
POST /scripts
围绕某个主题生成 2 个不同的旁白脚本版本,并根据目标时长调整脚本长度。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| prompt | string | 是 | 要撰写脚本的主题或创意。例如:“深海中 5 个令人震惊的事实”。 |
| duration | number | 是 | 目标视频时长,单位为秒(15-1200)。脚本长度会经过调整,以便旁白时长符合此目标。 |
| language | string | 否 | 脚本使用的语言(ISO 639-1 代码,例如 "en"、"es"、"hi")。默认值:英语。 |
| source | tool_page | inline | 否 | 请求的来源,仅用于分析。供仪表板使用;可以省略。 |
| templateId | string | 否 | 请求所使用的创作模板,仅用于分析。供仪表板使用;可以省略。 |
GET /image-styles
返回可在 POST /videos/generate 中作为 imageStyleId 使用的所有图像风格(当 mediaType 为 images 时):内置风格、精选模板风格(ID 形如 medical-xray,适用于 templateId: "medical"),以及在 AITuber 控制面板中创建的任何自定义风格。
GET /caption-styles
返回可在 POST /videos/generate 中作为 captionStyleId 使用的所有字幕风格:内置风格,以及在 AITuber 控制面板中创建的任何自定义风格。
POST /videos/generate
开始根据脚本、创意或文章、文档的文本生成新 AI 视频。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| thumbnail | object | 否 | |
| thumbnail.instructions | string | 否 | |
| script | string | 否 | 视频内容。此字段的用法取决于 inputType。脚本模式(inputType: "script",默认):提供准确的旁白文本。语音将逐字朗读这些内容。至少需要 5 个词。最多 30,000 个字符(足以制作一段以正常语速播放 20 分钟的视频)。AI 会自动将脚本拆分为视觉片段,并生成相应画面。**视觉控制:**默认情况下,AI 会决定旁白每个部分要呈现什么画面。如需更精细地控制,可在每段旁白前用方括号添加视觉指示:[A dark forest at night] The wind howled through the trees. [Glowing eyes peering from shadows] Something was watching. 每个 [bracketed text] 都会告诉 AI 该场景要呈现的具体画面。其后的文本将作为配音旁白。**在视频中呈现真实的人物、产品或地点(@提及):**使用句柄引用已保存的元素,例如 [@Maya holding @Red-Bottle] Meet the founder who started it all. 系统会将元素的参考照片提供给图像模型,确保整个视频中人物面孔或产品外观保持一致。通过 GET /elements 获取句柄;通过 POST /elements 创建新元素。规则:适用于 mediaType 为 images 和 video 的情况;不适用于 stock。元素外观由照片决定;不要在脚本中描述其外观。提及内容会以普通名称的形式朗读(不会读出 @),未知句柄会被视为普通词语。创意模式(inputType: "idea"):提供一个简短主题或概念。AI 会为你撰写完整的旁白脚本。长度应少于 800 个字符。搭配 expectedDurationSeconds 可控制视频时长。来源模式(inputType: "source"):提供文章、网页或文档的文本。此文本不是旁白。AI 会阅读文本,并据此撰写一段忠实于原文的简短旁白脚本。最多 200,000 个字符。需搭配 expectedDurationSeconds(必填)设置脚本长度,并搭配 source 对象说明文本来源。在来源模式下,可跳过此字段,改为发送 source.url(网页)或 source.assetId(已上传的 PDF)。制作视频时,我们会抓取并阅读网页或文件,因此你无需亲自阅读。支持任何语言。语音会以文本所用语言自然朗读。 |
| inputType | script | idea | source | 否 | 如何解读 script 字段。- script(默认):你的文本就是准确的旁白。朗读内容由你逐字掌控。- idea:你提供主题,AI 会为你撰写引人入胜的旁白脚本。使用 expectedDurationSeconds 控制目标时长。- source:提供文章或文档的文本,据此撰写简短视频脚本。AI 会忠实遵循原文,不会编造内容。expectedDurationSeconds 为必填项,因为它决定脚本时长。发送 source.url 或 source.assetId,我们会代你读取网页或 PDF;也可以在 script 中直接发送文本。 |
| source | object | 否 | 来源文本的来源。仅允许与 inputType: "source" 搭配使用;与其他 inputType 一起发送会返回 400。两种用法:发送 url 或 assetId,由我们自行读取网页或文件(此时无需提供 script);或者自行读取网页,并在 script 中发送文本。 |
| source.kind | url | document | 否 | 文本来源:网页使用 url,已上传的文件使用 document。 |
| source.url | string | 否 | 要读取的网页。与 kind: "url" 搭配使用。用此字段替代 script,制作视频时我们会抓取网页。网页必须公开;需要登录才能访问的网页无法读取。 |
| source.assetId | string (uuid) | 否 | 要读取的已上传 PDF。与 kind: "document" 搭配使用。用此字段替代 script,制作视频时我们会读取文件。请先上传文件以获取此 ID。 |
| source.mode | summarize | read-out | 否 | 对文本的处理方式。- summarize(默认):AI 会根据文本撰写一段忠实于原文的简短旁白,时长约为 expectedDurationSeconds。- read-out:文本本身就是旁白,逐字朗读。不会改写,也不会执行 AI 写作步骤。此模式下,expectedDurationSeconds 是上限:超出时长的文本会在句末截断,因此视频不会超过你指定的时长。 |
| source.title | string | 否 | 已知时填写网页或文档的标题。由我们自行读取网页时,此字段会被忽略。 |
| source.instructions | string | 否 | 你希望如何处理来源内容,例如“重点关注成本部分”或“保持积极基调”。最多 600 个字符。 |
| backgroundVideoId | string (uuid) | 否 | 背景模式使用的 ID,取自 GET /background-videos。一个片段会在整段旁白期间循环播放;来源音频会静音。 |
| mediaType | images | video | stock | background | avatar | 否 | 视频的画面类型。每种类型都会产生不同的观感。- images(默认):AI 为每个片段生成独特图像,并以平滑的 Ken Burns 平移/缩放动画呈现。这是热门 YouTube 频道常用的经典“无露脸旁白视频”风格。最受欢迎且最便宜的选项。使用 imageQuality 和 imageStyleId 控制画面风格。- video:AI 为每个片段生成短视频片段。比图像更生动、更具电影感,但消耗更多积分。skeleton 和 character 模板也会在内部使用此类型。- stock:自动为每个片段查找并匹配真实的素材库视频。适用于新闻、教育和纪录片风格的内容。- avatar:由虚拟形象朗读脚本的面对镜头视频。**需要提供 avatarId(取自 GET /avatars)和 voiceId。**仅支持脚本模式(不支持创意模式),最长 5 分钟,宽高比须为 9:16 或 16:9。每分钟视频约消耗 480 积分,另需支付旁白费用,远高于其他媒体类型。生成耗时也更长(通常为 3-10 分钟)。**大多数情况下,除非使用模板,否则建议保留默认值(images)。**使用 templateId 时,模板会自动为你选择最佳媒体类型,因此无需单独设置 mediaType。 |
| avatarId | string (uuid) | 否 | **当 mediaType 为 "avatar" 时必填。**朗读脚本的虚拟形象。通过 GET /avatars 获取有效 ID(包括内置虚拟形象和在控制面板中创建的角色)。其他媒体类型会忽略此字段。 |
| motionPrompt | string | 否 | 虚拟形象动作和手势的可选指示,例如“兴奋地边说边比划,身体靠近镜头”。仅适用于 mediaType 为 "avatar" 的情况。 |
| voiceId | string | 否 | 旁白语音 ID。通过 GET /voices 浏览全部 1,300 多种可用语音并试听,或使用通过 GET /voices/cloned 获取的克隆语音。若省略,默认使用“Adam”,一种低沉、自然的美式男声。例外:当 mediaType 为 "avatar" 时必填(没有默认值;请选择适合该虚拟形象的语音,或使用其 defaultVoiceId,该 ID 取自 GET /avatars)。使用 GET /voices 端点的查询参数,按性别、口音或用途筛选语音。选择前可通过每种语音的 previewUrl 试听样例。 |
| voiceSpeed | number | 否 | 旁白语速倍率。范围:0.7 到 1.2。- 0.7:慢 30%。适合教育、冥想内容或非母语受众。- 1.0(默认):自然语速。- 1.2:快 20%。适合活力十足、振奋人心或节奏快速的内容。大多数创作者使用 0.9 到 1.1 之间的值。 |
| aspectRatio | 9:16 | 16:9 | 1:1 | 否 | 视频尺寸。请根据计划发布的平台选择。- 9:16(默认):竖屏/纵向。最适合 YouTube Shorts、TikTok 和 Instagram Reels。- 16:9:横屏/横向。最适合标准 YouTube 视频和演示文稿。- 1:1:正方形。最适合 Instagram 信息流帖子和 LinkedIn。mediaType: "avatar" 不支持此选项。 |
| expectedDurationSeconds | number | 否 | 目标视频时长(秒)。当 inputType 为 "idea" 时必填,以便 AI 确定脚本长度。例如:30 表示 30 秒的 Shorts,60 表示 1 分钟视频,180 表示 3 分钟视频,600 表示 10 分钟视频,1200 表示 20 分钟视频。最大时长因模板而异:- 默认无露脸模板(不设置 templateId):1200 秒(20 分钟) - templateId: "skeleton" 或 templateId: "character":420 秒(7 分钟)(这些模板的成本结构不同,也不适用于长视频内容)- templateId: "rebuild":**60 秒(1 分钟)**当 inputType 为 "source" 时也必填,且适用于两种来源模式。对于 source.mode: "summarize",此值是目标时长:AI 会撰写一段时长约为该值的脚本。对于 source.mode: "read-out",此值是上限:文本会逐字朗读,超出时长的部分会在句末截断。若传入的值超出模板对应的上限,将返回 400 错误。inputType 为 "script" 时会忽略此字段,因为时长取决于词数。 |
| imageQuality | basic | good | premium | max | 否 | 图像生成质量等级。仅适用于 mediaType 为 "images" 的情况。质量越高,图像越详细、准确,但每张图像消耗的积分也越多。- basic(默认):每张图像 1 积分。生成速度快。适合测试和草稿。- good:每张图像 5 积分。细节和准确度更好。适合大多数已发布内容。- premium:每张图像 10 积分。细节丰富,与脚本高度吻合。适合专业内容。- max:每张图像 20 积分。最高质量。适合高制作水准的内容。典型的 60 秒视频包含 15-18 张图像(每 3-5 秒一张),请据此估算积分。每个等级都可以使用通过 @提及已保存元素的参考照片。每个场景使用的照片会在上述等级费用的基础上额外增加 3 积分。 |
| imageStyleId | string | 否 | AI 生成图像的视觉艺术风格。仅适用于 mediaType 为 "images" 的情况。每种风格都会让视频中的所有图像保持统一的美学风格。写实风格:- photorealistic(默认):超写实摄影,DSLR 画质。- cinematic:35mm 胶片质感、戏剧化光线、电影定格画面风格。- vintage-retro:1980 年代 VHS 美学、霓虹色彩、合成波氛围。- noir:经典黑白黑色电影风格、戏剧化阴影。插画风格:- 3d-pixar:Pixar 风格的 3D 卡通,造型圆润流畅。- anime:日本动漫/漫画风格,赛璐珞着色,色彩鲜艳。- digital-art:专业概念艺术,Artstation 水准。- comic-book:美国漫画风格,粗描边、半色调阴影。艺术风格:- pencil-sketch:在纹理纸张上绘制的精细石墨铅笔画。- oil-painting:可见笔触的古典油画。- watercolor:色彩透明、柔和的水彩画。- pop-art:Andy Warhol 风格,鲜明的原色。现代风格:- kurzgesagt:扁平矢量教育风格(类似该 YouTube 频道)。- pixel-art:复古 16 位电子游戏美学。- minimalist:简洁、朴素,大量留白。- claymation:Aardman 风格的定格黏土动画。另有 11 种风格。可与 imageStyleCustom 搭配进行微调。 |
| captionStyleId | string | 否 | 字幕的视觉风格。字幕会直接渲染到视频中,并与逐词时间同步。内置风格:- wrap-1(默认):高亮当前词,每组 2 个词。最受欢迎的风格。- cinematic:纤细白色字体,每个短语中的一个关键词采用发光斜体衬线字体。- koe:小号小写衬线字体,每次显示一个轻声短语。不高亮单词。- pill:白色圆角框上的黑色文字,每次显示一个简短短语。- hormozi:黑色圆角框上的粗体大写文字,带黄色高亮。灵感来自 Alex Hormozi。- beast:粗体 Bangers 字体,带字距弹跳动画。灵感来自 MrBeast。- noah:粗体斜体 Oswald 字体,带彩色高亮。- handwritten:自然随性的手写字体风格。亲切而真实。- subtitle:简洁的流媒体风格字幕,显示在深色背景条上。专业且易读。- impact:超大号粗体文字,每次显示一个词。强调效果突出。- pop:俏皮的弹簧动画搭配弹跳文字。活泼有趣。- chronicle:古典衬线字体,适合历史、神话和史诗故事。- cyber:未来感霓虹风格,适合科幻、科技和赛博朋克内容。- grit:原始马克笔风格,适合真实犯罪、街头和紧张刺激的故事。- luxe:优雅衬线字体,适合奢侈品、时尚和名人内容。- terminal:等宽字体风格,适合科技、黑客和 AI 内容。你也可以通过 AITuber 控制面板 使用自己的字体、颜色和动画创建自定义字幕风格。请在此处使用自定义风格 ID。 |
| captionsEnabled | boolean | 否 | 是否在视频中显示字幕。默认值:true。字幕会与旁白逐词自动同步。我们强烈建议保留字幕,因为字幕能显著提升互动率、无障碍性和观看时长。仅在纯音乐或环境音视频中设为 false。 |
| captionPosition | string | 否 | 字幕在视频中的垂直位置。- bottom(默认):字幕位于屏幕底部。- center:字幕位于屏幕中间。- top:字幕位于屏幕顶部。mediaType: "avatar" 不支持此选项(虚拟形象字幕始终使用默认位置)。 |
| videoQuality | string | 否 | 视频片段生成质量。仅适用于 mediaType 为 "video" 的情况。- basic:生成最快,画面质量较低。- good(默认):质量与速度较为均衡。- premium:高质量视频片段。生成速度较慢。- max:1080p 片段,画质最清晰。每秒成本最高。 |
| templateId | string | 否 | 应用特定视觉格式和风格的专用视频模板。留空则使用标准无露脸旁白视频(默认)。可用模板:- skeleton:采用骷髅/X 光画面的“如果……会发生什么”风格教育视频。内部使用 AI 视频生成。这是 YouTube Shorts 上热门的爆款形式。脚本示例:"What happens if you eat only ice cream for 30 days"。- medical:医学动画视频,解剖结构符合科学准确性,适用于健康教育、患者讲解和诊所内容。仅支持 mediaType 为 images(默认)或 video 的情况(不支持 stock:素材库中没有解剖结构画面)。可选的精选风格包括:medical-3d(写实 3D)、medical-translucent(半透明人体)、medical-xray、medical-darkstudio(黑色背景上的器官)、medical-cartoon(适合患者观看的卡通风格),也可省略此项以自动选择。创意示例:"How a total knee replacement works, step by step"。- character:由角色驱动的动画视频。AI 会在所有场景中生成同一个角色,并为其制作动画。内部使用 AI 视频生成。脚本示例:"A robot learns what friendship means on its first day at school"。- rebuild:AI 建造过程延时摄影。固定镜头呈现同一个地点从杂乱或空旷到完工的变化:摄像机不会移动,因此观众可以对比从第一秒到最后一秒的同一画面。没有旁白和字幕。观众会听到施工声,整个视频还会配上背景音乐。最后几秒始终会展示完工后的场所正在使用,而非空置状态。时长为 15-60 秒。可仅使用提示词、使用 beforeImageUrl 和 afterImageUrl,或任意组合。提示词必须描述一个正在发生变化的实体场所;讲课、笑话或产品评论会被拒绝。创意示例:"A dirty canal becomes a park with paths and lights"。**重要:**设置模板后,模板会为你处理视觉设置;只需提供 script(或使用 inputType: "idea" 并提供主题)。skeleton、character 和 rebuild 也会自动固定 mediaType。medical 则允许自由选择 mediaType:发送 images(默认)或 video;发送 stock 会返回 400。对于面对镜头的虚拟形象视频,请勿使用模板:请改为设置 mediaType: "avatar" 并提供 avatarId。 |
| beforeImageUrl | string | 否 | templateId: "rebuild" 使用的公开 HTTPS 图片 URL,作为第一帧。视频会从这张图片开始,整个过程中摄像机都保持相同角度。该场所不必真实存在;照片、绘图或渲染图均可。上传的图片不收费,并会替代原本生成的静帧,因此可降低积分成本。可选。其他模板会忽略此字段。 |
| afterImageUrl | string | 否 | templateId: "rebuild" 使用的公开 HTTPS 图片 URL,作为最后一帧。视频会以这张图片结束,摄像机角度与其他画面相同。图片通常是完工后场所的渲染图或绘图,而非照片,这也完全可以。上传的图片不收费,并会替代原本生成的静帧。可选。其他模板会忽略此字段。 |
GET /videos
返回组织中的所有视频,按最新优先排序。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | number | 否 | 每页返回的视频数量上限。默认值:50,最大值:100。 |
| cursor | string (uuid) | 否 | 分页游标:上一页中最后一个视频的 id。返回比该视频更早的视频。首页请省略此参数。返回空数组表示没有更多视频。 |
GET /videos/{id}
返回单个视频的详细信息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string (uuid) | 是 | 由 POST /generate 或 GET /videos 返回的视频 ID。 |
DELETE /videos/{id}
永久删除视频及其生成的资源。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string (uuid) | 是 | 要删除的视频 ID。 |
GET /clip-models
返回可用于独立片段生成的 AI 视频模型及其功能(文本生成视频、图像生成视频、参考图像)、支持的宽高比、分辨率、时长限制,以及各分辨率下每秒的积分费用。
POST /clips
开始根据文本提示词、图像或两者生成单个 AI 视频片段(1-30 秒)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 否 | 可选的片段标题。默认取提示词开头部分。 |
| modelKey | string | 是 | 要使用的生成模型。通过 GET /clip-models 获取有效键、功能和每秒费用。 |
| prompt | string | 否 | 描述片段应呈现的内容。文本生成视频模型必填;基于图像制作动画时可选。 |
| aspectRatio | auto | 16:9 | 9:16 | 4:3 | 3:4 | 1:1 | 21:9 | 3:2 | 2:3 | 9:21 | 5:4 | 4:5 | 否 | 片段尺寸。请通过 GET /clip-models 查看模型的 supportedAspectRatios。默认值:"16:9"。 |
| resolution | string | 否 | 输出分辨率(例如 "720p"、"1080p")。请查看模型的 supportedResolutions。更高分辨率每秒消耗的积分更多。默认值:"720p"。 |
| durationSeconds | integer | auto | 否 | 片段时长(秒);对于支持自动时长的模型,可设为 "auto"。默认值:5。 |
| firstFrameUrl | string | 否 | 用作首帧的公开图像 URL(图像生成视频)。仅适用于支持 supportsFirstFrame 的模型。 |
| lastFrameUrl | string | 否 | 用作末帧的公开图像 URL。仅适用于支持 supportsLastFrame 的模型。 |
| referenceImageUrls | array of string | 否 | 用作风格/主体参考的公开图像 URL。仅适用于支持 supportsReferenceImages 的模型;请遵守 maxReferenceImages 限制。 |
| referenceVideoUrls | array of string | 否 | 用于动作、编辑或扩展的公开视频 URL。请先查看模型功能。 |
| referenceAudioUrls | array of string | 否 | 用于语音、唇形同步、节奏或时间控制的公开音频 URL。请先查看模型功能。 |
GET /clips
返回独立生成的 AI 片段,按最新优先排序。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 每页片段数量上限(1-50)。默认值:20。 |
| cursor | datetime (ISO 8601) | 否 | 分页游标:上一页中最后一个片段的 createdAt。首页请省略此参数。 |
GET /clips/{id}
返回片段及其生成状态。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string (uuid) | 是 | 由 POST /clips 返回的片段 ID。 |
POST /exports
开始将已完成的视频渲染为可下载的 MP4 文件。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| videoId | string (uuid) | 是 | 要导出的视频 ID。视频的 status: completed。 |
| resolution | 1080p | 4k | 否 | 导出分辨率。- 1080p(默认):全高清(横屏为 1920x1080,竖屏为 1080x1920)。渲染速度快。- 4k:超高清(横屏为 3840x2160,竖屏为 2160x3840)。渲染速度较慢,文件更大。 |
GET /exports/download
返回用于下载已渲染视频 MP4 文件的临时签名 URL。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| videoId | string (uuid) | 否 | 视频 ID。查找该视频最新的已完成导出。 |
| exportId | string (uuid) | 否 | 特定的导出 ID,由 POST /exports 返回。通常无需填写,因为 videoId 会自动查找最新导出。 |
GET /channels
返回组织已连接的所有社交媒体频道(YouTube、TikTok、Instagram、Facebook、Threads 和 X)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| platform | youtube | tiktok | instagram | facebook | threads | x | all | 否 | 按平台筛选。使用 "all" 或省略此参数可列出所有已连接的频道。 |
POST /publications
将已完成的视频发布到一个或多个已连接的社交媒体渠道(YouTube、TikTok、Instagram、Facebook、Threads 和 X)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| videoId | string (uuid) | 是 | 要发布的视频。必须具有 status: completed。 |
| sceneExportId | string (uuid) | 否 | 如果视频已导出,可填写导出 ID。若省略,则会自动触发导出。 |
| caption | string | 否 | 用于 YouTube、TikTok、Instagram 和 Facebook 的描述或长文案。最多 2200 个字符。 |
| shortCaption | string | 否 | X 和 Threads 共用的短文案。长度会控制在 X 标准加权 280 字符限制内。若省略,默认使用 caption。 |
| addMadeWithCaption | boolean | 否 | 在每条文案末尾添加“Made with AITuber, the AI video generator: aituber.app”。默认值:true。必要时会缩短每条文案,以符合平台限制。 |
| publishNow | boolean | 否 | 设为 true(默认值)可立即发布。设为 false 并提供 scheduledAt 可安排发布时间。 |
| scheduledAt | datetime (ISO 8601) | 否 | 用于安排发布时间的 ISO 8601 日期时间。必须晚于当前时间。仅当 publishNow 为 false 时使用。 |
| channels | array of objects | 是 | 要发布到的一个或多个渠道。每个条目可包含特定平台的设置。 |
| channels[].channelId | string (uuid) | 是 | GET /channels 返回的渠道 ID。必须具有 status: connected。 |
| channels[].title | string | 否 | 视频标题(YouTube)。最多 100 个字符。默认使用生成视频时的标题。 |
| channels[].tags | array of string | 否 | 用于搜索发现的 YouTube 标签。最多 30 个标签,每个标签最多 100 个字符。 |
| channels[].categoryId | string | 否 | YouTube 类别 ID。默认值:“22”(People & Blogs)。常见类别:“24” Entertainment、“27” Education、“26” Howto & Style、“28” Science & Technology、“20” Gaming、“10” Music、“17” Sports、“1” Film & Animation、“23” Comedy。 |
| channels[].madeForKids | boolean | 否 | YouTube COPPA 合规标记。默认值:false。 |
| channels[].allowComment | boolean | 否 | 允许观众评论。默认值:true。仅 TikTok 和 X 支持。TikTok 会关闭评论。X 没有完全关闭评论的选项,因此会将回复限制为你提及的账号。YouTube、Instagram、Facebook 和 Threads 会忽略此项。 |
| channels[].tiktokPrivacyStatus | public | friends | private | 否 | 隐私设置。默认值:“public”。 |
| channels[].allowDuet | boolean | 否 | 允许合拍。默认值:true。 |
| channels[].allowStitch | boolean | 否 | 允许拼接。默认值:true。 |
| channels[].isAiGenerated | boolean | 否 | 在 TikTok 上将视频标记为 AI 生成。默认值:false。 |
| channels[].instagramPlacement | reels | stories | timeline | 否 | Instagram:发布位置。默认值:“reels”。 |
| channels[].shareToFeed | boolean | 否 | Instagram:同时将 Reels 分享到动态。默认值:true。 |
GET /publications/{publicationId}
返回发布内容的当前状态。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| publicationId | string (uuid) | 是 | POST /publications 返回的发布 ID。 |
DELETE /publications/{publicationId}
在未来安排的发布内容上线前取消发布。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| publicationId | string (uuid) | 是 | 要取消的发布 ID。 |
GET /subscription
返回你当前的套餐和积分余额。
GET /background-videos
列出背景视频 无需身份验证。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| categorySlug | string | 否 | |
| cursor | string (uuid) | 否 |
GET /background-videos/categories
列出背景视频类别 无需身份验证。
POST /uploads/confirm-background-video
确认背景视频上传 无需身份验证。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| assetId | string (uuid) | 是 | |
| title | string | 是 |
积分消耗
| 操作 | 消耗 |
|---|---|
| 图像(基础) | 1 积分/张 |
| 图像(良好) | 5 积分/张 |
| 图像(优质) | 10 积分/张 |
| 图像(最高) | 20 积分/张 |
| 场景中的每张参考照片 | +3 积分 |
| 音频旁白 | 约 30 积分/分钟 |
| AI 视频片段(基础) | 5 积分/秒(约 25 积分/个 5 秒片段) |
| AI 视频片段(良好) | 10 积分/秒(约 50 积分/个 5 秒片段) |
| AI 视频片段(优质) | 26 积分/秒(约 130 积分/个 5 秒片段) |
| AI 视频片段(最高) | 30 积分/秒(约 150 积分/个 5 秒片段) |
| 素材视频 | 约 50 积分/分钟 |
| 背景视频 | 10 积分/分钟,另加旁白费用 |
| 导出为 MP4 | 免费 |
| 发布 | 免费 |
一段典型的 60 秒视频,使用基础图像质量,费用约为 47 积分(旁白 + 约 17 张图像)。生成前,请使用 GET /subscription 查看余额。
错误处理
| HTTP 状态 | 含义 |
|---|---|
| 400 | 请求错误(查看错误消息了解详情) |
| 401 | 缺少或无效的 API 密钥 |
| 402 | 积分不足。响应中包含 creditsRequired 和 creditsAvailable |
| 403 | 此功能需要有效的付费订阅 |
| 404 | 未找到资源 |
402 和 403 表示套餐或积分限制,而不是程序错误
出现这些响应时不会丢失任何内容,也不会扣除积分。不要只报告失败然后停止。请用通俗的语言说明缺少什么,说明各套餐包含的内容,并提供用户管理套餐和积分的页面:https://app.aituber.app/dashboard/billing。不要推荐套餐、比较价格或推动升级。购买只能在网站上进行,不能通过 API 进行。
402 PAYMENT_REQUIRED 表示积分余额不足。creditsRequired 和 creditsAvailable 会显示差额。付费套餐包含积分,并会在每个结算周期补充积分。
始终可以选择更省的方案:缩短脚本、选择 mediaType: "images" 而非 "video",或选择 imageQuality: "basic"。应将其作为选项提供,切勿静默降级。
403 PAID_PLAN_REQUIRED(导出时的消息为 PAID_PLAN_REQUIRED_FOR_EXPORT,且 data.feature = export 或 other)表示账户没有付费套餐。MP4 下载、单个 AI 片段生成和 UGC 反应片段仅包含在付费套餐中。套餐生效后,请重试调用。
403 PUBLISH_FEATURE_REQUIRED 表示发布功能从 Creator 套餐起提供。发布本身不消耗积分。
有意不提供购买积分或套餐的端点。积分永不过期,且 GET /subscription 始终返回当前套餐和余额。切勿编造价格、折扣、节省金额或收入数据;只引用 API 返回的内容。
完整示例(bash)
# 1. Check credits
curl -s "https://app.aituber.app/api/v1/subscription" \
-H "Authorization: Bearer $AITUBER_API_KEY" | jq .
# 2. Browse voices
curl -s "https://app.aituber.app/api/v1/voices?gender=female&useCase=narration" | jq '.[0:3]'
# 3. Generate video (omit voiceId to use the default voice)
VIDEO_ID=$(curl -s -X POST "https://app.aituber.app/api/v1/videos/generate" \
-H "Authorization: Bearer $AITUBER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"script": "Did you know that octopuses have three hearts and blue blood?",
"imageStyleId": "cinematic",
"aspectRatio": "9:16"
}' | jq -r '.videoId')
echo "Video ID: $VIDEO_ID"
# 4. Poll until completed
while true; do
STATUS=$(curl -s "https://app.aituber.app/api/v1/videos/$VIDEO_ID" \
-H "Authorization: Bearer $AITUBER_API_KEY" | jq -r '.status')
echo "Status: $STATUS"
if [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ]; then break; fi
sleep 10
done
# 5. Export to MP4
curl -s -X POST "https://app.aituber.app/api/v1/exports" \
-H "Authorization: Bearer $AITUBER_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"videoId\": \"$VIDEO_ID\"}"
# 6. Poll export status
while true; do
EXPORT_STATUS=$(curl -s "https://app.aituber.app/api/v1/videos/$VIDEO_ID" \
-H "Authorization: Bearer $AITUBER_API_KEY" | jq -r '.exportStatus')
echo "Export: $EXPORT_STATUS"
if [ "$EXPORT_STATUS" = "completed" ] || [ "$EXPORT_STATUS" = "failed" ]; then break; fi
sleep 10
done
# 7. Download
DOWNLOAD_URL=$(curl -s "https://app.aituber.app/api/v1/exports/download?videoId=$VIDEO_ID" \
-H "Authorization: Bearer $AITUBER_API_KEY" | jq -r '.url')
curl -L -o video.mp4 "$DOWNLOAD_URL"
echo "Downloaded: video.mp4"