讲解视频 API
用你自己的代码创建带旁白的可视化讲解视频,然后分享、嵌入或删除它们,还能把旁白读成文字。一共六个端点,一个 API 密钥,请求和响应都是 JSON。
API 目前处于 beta 阶段。如需使用,请申请 API 访问权限。
基础知识
所有端点都在同一个基础 URL 下,并且都返回 JSON。
https://scrimba.com/api/v1每个请求都要把你的 API 密钥作为 bearer token 发送:
Authorization: Bearer scr_live_…请求体使用 application/json;带文件时使用 multipart/form-data。响应中的日期是 UTC 时间的 ISO 8601 字符串。id 是不透明的字符串。错误响应也是 JSON,见错误。
版本号写在路径里。响应中可能会新增字段,而不升级版本;但在 v1 内,任何字段都不会被删除或重命名。
API 密钥
每个密钥都属于一个 Scrimba 账户。用这个密钥创建的所有内容都归该账户所有,从该账户的每月额度中扣除,并且在网站上显示在该账户下。
- 登录 scrimba.com。从个人资料菜单打开设置(Settings),然后进入 API 密钥(API keys)部分。
- 选择创建 API 密钥(Create API key)并给它起个名字,比如用将要保存它的服务器来命名。
- 从对话框中复制密钥值。它以 scr_live_ 开头,只显示一次:Scrimba 只保存它的哈希值。
API 目前处于 beta 阶段。账户需要先获得 API 访问权限,才能打开密钥对话框。在 Scrimba 为该账户开通之前,对话框和每个 API 调用都会返回 403 api_not_enabled。
把密钥值保存在你的服务器上,绝不要放在浏览器或你发布的应用里。要停用一个密钥,在同一部分中找到它所在的那一行,选择撤销(Revoke)。被撤销的密钥此后都会返回 401,而且无法恢复;需要的话请新建一个。一个账户最多有 20 个有效密钥,它们共享该账户的所有限制。
下面的示例使用两个 shell 变量:
export SCRIMBA=https://scrimba.com
export SCRIMBA_KEY=scr_live_your_secret_here快速上手
创建一个讲解视频,等它生成完成,然后分享它的链接。创建请求会立即返回;讲解视频在后台生成,生成过程中它的页面会实时渲染。
const base = 'https://scrimba.com/api/v1'
const headers = {Authorization: `Bearer ${process.env.SCRIMBA_KEY}`}
const created = await fetch(`${base}/explainers`, {
method: 'POST',
headers: {...headers, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID()},
body: JSON.stringify({prompt: 'Explain how the Node.js event loop schedules work', privacy: 'unlisted'})
})
if (!created.ok) throw new Error((await created.json()).error.message)
let explainer = await created.json()
while (explainer.status === 'generating') {
await new Promise(resolve => setTimeout(resolve, 5000))
explainer = await (await fetch(`${base}/explainers/${explainer.id}`, {headers})).json()
}
console.log(explainer.status, explainer.url)短的讲解视频不到一分钟就能完成,长的可能需要几分钟。大约每 5 秒轮询一次即可。
GET /api/v1/me
返回密钥所属的账户、密钥本身、账户的等级和本月用量,以及创建端点接受的各项取值。
curl -s "$SCRIMBA/api/v1/me" -H "Authorization: Bearer $SCRIMBA_KEY"{
"account": {"id": "u1a2b3c", "alias": "acme", "name": "Acme Learning"},
"key": {"id": "ak9x", "name": "server", "prefix": "scr_live_abc123", "created_at": "2026-10-09T10:12:00.000Z"},
"tier": {"name": "pro", "requests_per_minute": 120, "concurrent_generations": 3, "explainers_per_month": 100},
"explainers": {"used": 12, "remaining": 88, "resets_at": "2026-11-01T00:00:00.000Z"},
"teachers": ["eli5", "standard", "per", "tom", "lol", "professor", "tldr"],
"modes": ["landscape", "portrait", "square"],
"privacy": ["private", "unlisted", "public"]
}key.prefix 是密钥值的开头部分,足以区分不同的密钥。tier.explainers_per_month 是该账户的每月上限:套餐的数字,或 Scrimba 为该账户单独设置的数字。explainers.resets_at 是每月计数重新开始的时间。
POST /api/v1/explainers
创建一个讲解视频并开始生成。讲解视频一创建出来,就会返回 201 和讲解视频对象;此时 status 为 generating。
字段
| 字段 | 取值 | 默认值 |
|---|---|---|
prompt | 要讲解的内容,最多 12,000 个字符的字符串。除非请求带有附件,否则必填。 | |
mode | landscape(16:9)、portrait(9:16)、square(1:1)。幻灯片的形状。 | landscape |
privacy | private(仅你的账户可见)、unlisted(任何拥有链接的人可见)、public(在网站上公开列出)。 | private |
language | ISO 639-1 代码,例如 en 或 pt-BR。无论提示词是什么语言,旁白和画面上的文字都会使用该语言。带地区的代码(如 pt-BR)会选择对应的方言。 | 提示词的语言 |
teacher | eli5、standard、per、tom、lol、professor、tldr。讲解的声音和风格。 | eli5 |
watermark | true 或 false。false 需要 Pro 账户。 | true |
attachments | multipart 文件部分,最多 5 个。见附件。 | |
cite_attachments | true 或 false。为 true 时,旁白会引用它所讲解的文本附件片段,文字稿会带上这些引用。 | false |
省略的字段,或以 null 发送的字段,会使用默认值。你发送的字段必须给出一个取值:language: false 会被拒绝,privacy: false 也一样。
JSON
curl -s "$SCRIMBA/api/v1/explainers" \
-H "Authorization: Bearer $SCRIMBA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-4821-explainer" \
-d '{
"prompt": "Explain how HTTP caching headers decide what a browser keeps",
"mode": "landscape",
"privacy": "unlisted",
"language": "en",
"teacher": "standard"
}'Multipart(带附件)
发送 multipart/form-data 格式的请求体。文本字段和 JSON 方式相同。每个文件作为一个名为 attachments 的部分添加。只要至少有一个附件,prompt 就是可选的。
curl -s "$SCRIMBA/api/v1/explainers" \
-H "Authorization: Bearer $SCRIMBA_KEY" \
-F "prompt=Walk through this diagram and the code behind it" \
-F "mode=portrait" \
-F "[email protected]" \
-F "[email protected]"幂等性
发送一个 Idempotency-Key 请求头,值是你自己定义的字符串,长度为 1 到 200 个可打印字符,每个你打算创建的讲解视频用一个值。如果请求在你读到响应之前就中断了,就用同一个 API 密钥和同一个请求头值重新发送:API 会返回它已经创建的那个讲解视频,状态码是 200 而不是 201,不会再创建第二个。使用同一个请求头值、同时到达的两个请求只会创建一个讲解视频。请求头值按 API 密钥分别记录;讲解视频被删除后,它的请求头值就可以再次使用。
响应
{
"id": "guide0abc123",
"url": "https://scrimba.com/explain/guide0abc123",
"status": "generating",
"error": null,
"title": "Explain how HTTP caching headers decide what a browser keeps",
"description": null,
"mode": "landscape",
"privacy": "unlisted",
"language": null,
"created_at": "2026-10-09T10:15:02.000Z",
"finished_at": null,
"video_url": null,
"embed": "<iframe src=\"https://scrimba.com/explain/guide0abc123\" …></iframe>",
"attachments": [],
"duration_ms": 0
}你可以立即打开或分享 url。页面会显示讲解视频的生成过程,完成后就会播放。
被拒绝的创建请求不会创建任何内容,也不会消耗额度。超出本月额度的创建请求会返回 429 quota_exceeded;如果账户正在运行的生成数已达到其等级上限,则返回 429 too_many_running。两者都带有 Retry-After。
GET /api/v1/explainers/:id
返回该账户通过 API 创建的某一个讲解视频及其当前状态。
curl -s "$SCRIMBA/api/v1/explainers/guide0abc123" -H "Authorization: Bearer $SCRIMBA_KEY"status 会从 generating 变为 ready 或 failed,之后不再变化。变为 ready 时,finished_at、language 和 duration_ms 会被填入。变为 failed 时,error 会说明原因,url 对应的页面会显示讲解视频生成失败,而且这个讲解视频不计入本月用量:它占用的额度会退回。如果生成中途停止而没有完成(例如服务器重启),十分钟后会被报告为 failed。
在网站上创建的讲解视频,或其他账户通过 API 创建的讲解视频,都会返回 404。
GET /api/v1/explainers/:id/transcript
已就绪讲解视频的旁白:每个口述片段一条记录,按播放顺序排列,并附上每个片段引用的附件片段。旁白照常指向幻灯片;引用则说明它的文字出自哪里。
讲解视频生成中或已失败时,响应是 409 not_ready。在网站上创建的讲解视频,或其他账户通过 API 创建的讲解视频,都会返回 404。
curl -s "$SCRIMBA/api/v1/explainers/guide0abc123/transcript" -H "Authorization: Bearer $SCRIMBA_KEY"{
"id": "guide0abc123",
"attachments": [{"ref": 1, "name": "server.ts", "type": "text/plain"}],
"entries": [
{
"index": 3,
"slide": 2,
"title": "Checking the token",
"text": "The handler reads the token from the header, then compares it to the stored secret.",
"references": [
{
"text": "reads the token from the header",
"text_start": 12,
"text_end": 43,
"attachment": 1,
"offset": 412,
"length": 39,
"lines": [10, 10],
"cited_text": "const token = req.headers.authorization"
}
]
}
]
}| 字段 | 类型 | 含义 |
|---|---|---|
attachments | array | 与讲解视频对象携带的列表相同,所以一次调用就够了。 |
entries[].index | number | 该记录在旁白中的位置,从 0 开始。 |
entries[].slide | number | 该记录播放时显示的幻灯片,从 0 开始。 |
entries[].title | string 或 null | 讲解视频给这个片段的旁白标题。 |
entries[].text | string | 口述的文字,与页面上文字稿显示的一致。 |
entries[].references | array | 该记录引用的附件片段,按旁白列出的顺序排列。没有引用时为空。 |
references[].text | string | text 中被该引用支撑的文字。 |
references[].text_start, text_end | number 或 null | 这些文字在 text 中的位置:第一个字符的索引,以及最后一个字符之后的索引。当旁白没有按引用给出的原文逐字说出时为 null。 |
references[].attachment | number | 被引用文件在 attachments 中的 ref。 |
references[].offset, length | number | 文件中被引用的片段:起始字符位置和字符数。 |
references[].lines | array | 被引用片段的首行和末行,从 1 开始计数。 |
references[].cited_text | string | 被引用的片段本身。 |
引用来自创建时的 cite_attachments: true;引用介绍了怎么使用。没有它时,每个 references 列表都为空。只会引用文本和代码文件,绝不会引用图片或 PDF。
文本文件最多读取 30,000 个字符,offset 在已读取的范围内计数。在文件中找不到所引片段的引用会被省略。
GET /api/v1/explainers
分页返回该账户通过 API 创建的讲解视频,最新的排在最前。在网站上创建的讲解视频不在列表中。
| 查询参数 | 取值 | 默认值 |
|---|---|---|
limit | 每页行数,1 到 100。 | 25 |
cursor | 上一页的 next_cursor。 | 第一页 |
curl -s "$SCRIMBA/api/v1/explainers?limit=25" -H "Authorization: Bearer $SCRIMBA_KEY"
# {"explainers": [{…}, {…}], "next_cursor": "guide0abc123"}
curl -s "$SCRIMBA/api/v1/explainers?limit=25&cursor=guide0abc123" -H "Authorization: Bearer $SCRIMBA_KEY"
# {"explainers": [{…}], "next_cursor": null}每一行都是一个不含 duration_ms 的讲解视频对象。最后一页的 next_cursor 为 null。cursor 对应的讲解视频被删除后,这个 cursor 仍然有效;如果一个 cursor 从未对应过该账户通过 API 创建的讲解视频,则返回 400 invalid_cursor。
DELETE /api/v1/explainers/:id
删除该账户通过 API 创建的某一个讲解视频;如果它有导出的视频,也会一并删除。讲解视频的页面和链接会失效,此后该讲解视频会返回 404。它占用的额度不会退回。
curl -s -X DELETE "$SCRIMBA/api/v1/explainers/guide0abc123" -H "Authorization: Bearer $SCRIMBA_KEY"
# {"deleted": "guide0abc123"}讲解视频对象
POST、GET 和列表接口为单个讲解视频返回的内容。
| 字段 | 类型 | 含义 |
|---|---|---|
id | string | 讲解视频的 id,用在上面的路径中。 |
url | string | 讲解视频的页面。谁能打开它取决于 privacy。 |
status | string | generating、ready 或 failed。 |
error | object 或 null | status 为 failed 时是 {"code": "generation_failed", "message": "…"};否则为 null。 |
title | string | 讲解视频的标题:即提示词;没有提示词时,是根据附件得出的名称。 |
description | string 或 null | 简短的内容概要,在讲解视频完成后填入。 |
mode | string | landscape、portrait 或 square。 |
privacy | string | private、unlisted 或 public。 |
language | string 或 null | 旁白语言,格式为 en-us 这样的标签。讲解视频完成前为 null。 |
created_at | string | 讲解视频的创建时间。 |
finished_at | string 或 null | 生成完成的时间;生成过程中或生成失败后为 null。 |
video_url | string 或 null | 讲解视频的 MP4 文件。只有已经导出过视频、并且讲解视频为 unlisted 或 public 时才会填入。 |
embed | string 或 null | 用于你自己网页的 <iframe> 代码片段。只有讲解视频为 unlisted 或 public 时才会填入:private 讲解视频的 iframe 对除你以外的所有人都只显示登录提示。 |
attachments | array | 随请求发送的文件,按发送顺序排列:{"ref": 1, "name": "server.ts", "type": "text/plain"}。ref 是讲解视频用来指代该文件的编号。 |
duration_ms | number | 播放时长,单位为毫秒;讲解视频完成前为 0。只出现在 POST 和 GET 的响应中,列表中没有。 |
附件
一个请求最多可以带 5 个文件,作为名为 attachments 的 multipart 部分发送。讲解视频会把它们当作上下文来读取,并可以展示其中的图片。
| 类型 | 接受的格式 | 限制 |
|---|---|---|
| 图片 | png, jpeg, gif, webp | 每个最大 5 MB、3000 万像素 |
| application/pdf | 每个最大 5 MB | |
| 文本和代码 | 任意 text/* 类型,或文件名以 txt, md, log, env, conf, cfg, ini, js, jsx, ts, tsx, py, json, imba, html, css 结尾 | 每个最多 30,000 个字符 |
| Jupyter notebook | 文件名以 .ipynb 结尾 | 以 markdown 形式存储,按文本计算:30,000 个字符 |
图片和 PDF 按文件的实际字节判断类型,与该部分声明的 content type 无关。其他文件按声明的类型判断;如果该部分没有声明类型,或声明的是 application/octet-stream,则按实际字节判断。其他类型的文件会返回 415 unsupported_attachment,超出限制的文件会返回 413 too_large;两种错误都会指出是哪个文件。被拒绝的请求不会保存任何内容。
整个请求体最大 32 MB。JSON 请求体最大 256 KB。
限制
| 限制 | 免费 | Pro |
|---|---|---|
| 每个账户每月的讲解视频数 | 5 | 100 |
| 每个账户同时运行的生成数 | 1 | 3 |
| 每分钟请求数(账户所有密钥合计) | 30 | 120 |
| watermark: false | 否 | 是 |
Pro 指该账户的 Scrimba Pro 订阅。Scrimba 可以为某个账户单独设置每月上限,包括 0;GET /api/v1/me 和 quota_exceeded 响应会告知实际生效的上限。
每月计数在每月 1 日(UTC)重置;GET /api/v1/me 会返回确切时间。只有实际创建的讲解视频才计数,生成失败的讲解视频会退回额度。被拒绝的请求不消耗任何额度。
因超出限制而被拒绝时,会返回 429 和一个以秒为单位的 Retry-After 响应头。请等这段时间过去再重试,不要立即重试。
错误
所有错误都返回同一种结构的 JSON,HTTP 状态码表示错误的类别,code 表示具体原因:
{"error": {"code": "invalid_prompt", "message": "The prompt is over 12000 characters"}}| 状态码 | 错误码 | 含义 |
|---|---|---|
| 400 | invalid_prompt, invalid_mode, invalid_privacy, invalid_language, invalid_teacher, invalid_watermark, invalid_cite_attachments, too_many_attachments, invalid_json, invalid_multipart, invalid_idempotency_key, invalid_limit, invalid_cursor | 某个字段、请求头或请求体有误。message 会说明是哪一个。 |
| 401 | unauthorized | bearer token 缺失、无法识别或已被撤销。 |
| 403 | api_not_enabled | 该账户尚未开通 API。 |
| 403 | pro_required | 在没有 Pro 的账户上使用了 watermark: false。 |
| 404 | not_found | 该账户下没有这个 id 的讲解视频,或它已被删除。 |
| 409 | not_ready | 请求了仍在生成中或已失败的讲解视频的文字稿。 |
| 413 | too_large | JSON 请求体超过 256 KB,multipart 请求体超过 32 MB,图片或 PDF 超过 5 MB 或 3000 万像素,或文本文件超过 30,000 个字符。message 会指出是哪个文件。 |
| 415 | unsupported_attachment, unsupported_media_type | 文件类型不是讲解视频接受的类型,或请求体既不是 JSON 也不是 multipart。 |
| 429 | rate_limited | 超出了该账户每分钟的请求数,或全站正在上传的图片过多。请等待 Retry-After 指定的时间。 |
| 429 | too_many_running | 该账户正在运行的生成数已达到其等级上限。请等待 Retry-After 指定的时间,或等某个生成完成。 |
| 429 | quota_exceeded | 本月的讲解视频额度已用完。message 会说明计数何时重置。 |
| 503 | busy | 服务器当前正在处理的上传过多。请稍后重试。 |
| 500 | internal | Scrimba 端出现故障。请稍后重试;如果问题一直存在,请联系 Scrimba,并提供发生的时间,如果有讲解视频 id 也一并提供。 |
本页描述的是截至 2026 年 10 月 20 日的讲解视频 API。

