REST API|影片字幕 API

為任何影片加字幕
只要三次 API 呼叫

送出影片網址,回傳一支已壓上逐字字幕的 mp4。Whisper 對齊每個字,AI 挑出要強調的詞,算圖跑在我們的 worker 叢集上。

POSThttps://autostud.ai/api/v1/actions/subtitles.generate
快速開始

整段流程,一個檔案

貼上、填入金鑰、執行。這裡沒有任何虛擬碼。

const API = 'https://autostud.ai/api/v1'
const KEY = process.env.AUTOSTUD_API_KEY

const call = async (path, body) => {
  const response = await fetch(API + path, {
    method: body ? 'POST' : 'GET',
    headers: {
      Authorization: `Bearer ${KEY}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  })

  const payload = await response.json()
  if (!response.ok) throw new Error(payload.error?.message || response.statusText)
  return payload
}

// 1. A video project to hang the timeline on.
const created = await call('/actions/videos.create', {
  video_name: 'Interview clip',
  video_type_id: 'timeline',
  video_format: 'portrait',
  video_lang: 'en',
})
const video_id = created.data.video_id

// 2. Transcribe, emphasise, style — one call.
const subtitled = await call('/actions/subtitles.generate', {
  video_id,
  media_url: 'https://cdn.example.com/interview.mp4',
  style_preset: 'beast',
  words_per_group: 3,
})
console.log(subtitled.data.word_count, 'words', subtitled.data.duration_seconds, 's')

// 3. Render it.
await call('/actions/renders.create', {
  video_id,
  video_type_id: 'timeline',
  video_format: 'portrait',
})

// 4. Wait for the worker. A webhook is better; this is the short version.
let render
do {
  await new Promise((resolve) => setTimeout(resolve, 15000))
  const list = await call(`/renders?video_id=${video_id}&limit=1`)
  render = list.data[0]
} while (render && ['not_started', 'processing'].includes(render.render_status))

if (render.render_status !== 'done') throw new Error('Render failed')
console.log(render.render_url)

基底網址:https://autostud.ai/api/v1 — 以 `Authorization: Bearer sk_live_…` 驗證。`sk_test_` 金鑰會走完全相同的路徑,並在花費之前停下。

逐步

你真正要做的事

六個步驟,其中四個各只是一次請求。

  1. 1

    建立 API 金鑰

    後台 → 設定 → API 金鑰。不想自己挑 scope 就選「Automation」預設,它涵蓋影片、算圖與檔案。密鑰只顯示一次。`sk_live_` 會花費,`sk_test_` 驗證整個請求並在寫入前停下。

    export AUTOSTUD_API_KEY="sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    
    # What can this key actually do?
    curl https://autostud.ai/api/v1 \
      -H "Authorization: Bearer $AUTOSTUD_API_KEY"
  2. 2

    把影片放到一個網址後面

    沒有上傳端點:API 讀的是網址。你的儲存桶、你的 CDN、一個簽名連結 — 只要我們的伺服器抓得到就行。要不要登記到工作區檔案庫是選擇性的,不影響流程。

    # The API takes a URL, never a file upload. Anything publicly
    # reachable works: your bucket, your CDN, a signed URL.
    export MEDIA_URL="https://cdn.example.com/interview.mp4"
    
    # Optional: keep a record of it in the workspace library.
    curl -X POST https://autostud.ai/api/v1/assets \
      -H "Authorization: Bearer $AUTOSTUD_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "provider_file_url": "'"$MEDIA_URL"'",
        "provider_file_name": "interview.mp4",
        "file_mime_type": "video/mp4",
        "provider_file_id": "interview-2026-08-18",
        "sync_method": "api"
      }'
  3. 3

    建立影片專案

    `videos.create` 會回傳 `video_id`,後面的一切都掛在它底下。帶上 `Idempotency-Key`,重送時會回傳第一次的結果,而不是再開一個專案。

    curl -X POST https://autostud.ai/api/v1/actions/videos.create \
      -H "Authorization: Bearer $AUTOSTUD_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: interview-2026-08-18" \
      -d '{
        "video_name": "Interview clip",
        "video_type_id": "timeline",
        "video_format": "portrait",
        "video_lang": "en"
      }'
  4. 4

    加上字幕

    `subtitles.generate` 在伺服器端一次做完:Whisper 逐字轉寫並對齊,AI 標出要強調的詞,再套上 116 種樣式之一。回應會給你字數、精確長度與偵測到的語言。

    export VIDEO_ID="9f0c4e2a-1d6b-4a77-9d51-6b0f2e8c3a4d"
    
    curl -X POST https://autostud.ai/api/v1/actions/subtitles.generate \
      -H "Authorization: Bearer $AUTOSTUD_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "video_id": "'"$VIDEO_ID"'",
        "media_url": "'"$MEDIA_URL"'",
        "style_preset": "beast",
        "words_per_group": 3,
        "enable_emphasis": true,
        "enable_diarization": false
      }'
  5. 5

    送出算圖

    `renders.create` 把工作丟到 worker 叢集,並立刻回傳 `render_id`。一次算圖固定 20 點數,不論影片多長。

    curl -X POST https://autostud.ai/api/v1/actions/renders.create \
      -H "Authorization: Bearer $AUTOSTUD_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "video_id": "'"$VIDEO_ID"'",
        "video_type_id": "timeline",
        "video_format": "portrait"
      }'
  6. 6

    取回 mp4

    訂閱 `render.completed`,完成的網址會帶簽名推給你。想自己拉也行:列出該影片的算圖並讀 `render_status`,直到變成 `done`。

    # Register once, then stop polling.
    curl -X POST https://autostud.ai/api/v1/webhooks \
      -H "Authorization: Bearer $AUTOSTUD_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://your-app.com/hooks/autostud",
        "events": ["render.completed", "render.failed"],
        "description": "Subtitled videos"
      }'
    # The signing secret comes back once, in this response. Store it.
參考

本頁用到的每一個呼叫

Scope 指的是金鑰必須具備的權限,不是你要傳的欄位。

呼叫Scope作用
GET /api/v1-探索:這把金鑰能做什麼、有哪些限制、用了多少。
POST /api/v1/actions/videos.createvideos:write建立影片專案並回傳其識別碼。
POST /api/v1/actions/subtitles.generatevideos:execute轉寫、標重點、套樣式,並存下字幕軌。
POST /api/v1/actions/renders.createrenders:execute把算圖排進 worker 叢集。20 點數。
GET /api/v1/renders?video_id=…renders:read某支影片的算圖列表(最新在前),含狀態與網址。
POST /api/v1/webhookswebhooks:write註冊一個 https 端點,並一次性回傳其簽章密鑰。

樣式預設

在 `style_preset` 傳一個即可。每個預設會一併決定字體、外框、強調色與動畫 — 沒有其他要調的東西。

makeitlookeasy
default4 個字 · simple
makeitloud
bold3 個字 · simple
thisoneword
impact3 個字 · focus_on_one_word
huge
beast1 個字 · focus_on_one_word
onewordatatime
karaoke5 個字 · focus_on_one_word
itfillsasyousing
karaoke_fill5 個字 · karaoke
lightsonthewords
neon4 個字 · progressively_visible
nothingbehindthetextatall
minimal6 個字 · simple
wordbywordtheyland
pop5 個字 · progressively_visible
darktextonapill
pill5 個字 · simple
twocalmlinesatthebottomoftheframe
cinematic9 個字 · simple

動手前該知道的事

  • 流量限制以金鑰為單位,並在標頭回覆:`X-RateLimit-Limit`、`X-RateLimit-Remaining`,429 時還有 `Retry-After`。
  • 任何 POST 帶上 `Idempotency-Key`,24 小時內重送都是安全的,會原樣重播第一次的回應。
  • `sk_test_` 金鑰會實際跑過驗證、scope、限制與欄位檢查,然後回 `simulated: true`,不寫入也不花費。
  • 錯誤是有型別的:`invalid_request`、`insufficient_credits`、`rate_limit_exceeded`、`upstream_error` — 請依代碼分支,別依訊息。

失敗的時候

每個錯誤都是同一個形狀:可用來分支的固定 `code`、直接點名修正方式的 `hint`,以及回報時附上的 `request_id`。完整代碼清單在 /docs/api/errors。

代碼代表什麼
401 missing_credentials請求裡沒有金鑰,或是我們不認得的金鑰。
403 insufficient_scope金鑰少了 scope;`details.required_scopes` 會指名。
422 validation_failed有欄位不對;`details.issues` 會逐一列出。
402 insufficient_credits算圖的點數不足。儲值,或改用測試金鑰。
429 rate_limit_exceeded呼叫太頻繁。等 `Retry-After` 秒後再試。
502 upstream_error我們依賴的供應商掛了。退避後重試。
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This API key is missing the required scope: videos:execute.",
    "details": {
      "required_scopes": ["videos:execute"],
      "granted_scopes": ["videos:read", "videos:write"]
    },
    "hint": "`details.required_scopes` lists what is missing. Call GET /api/v1 to see what this key does hold, then re-scope it at /app/settings/api-keys.",
    "retryable": false,
    "request_id": "req_8f2c41d0a95b",
    "doc_url": "https://autostud.ai/docs/api/errors#insufficient_scope"
  }
}

錯誤代碼

Webhook

別再輪詢了

算圖要幾分鐘。讓結果自己來找你。

有簽章,十行就能驗

`X-Autostud-Signature: t=<unix>,v1=<hex>` 是對 `"<timestamp>.<原始 body>"` 做的 HMAC-SHA256。請在解析之前,用原始 body 驗證。

重送由我們處理

約兩小時內重試五次,而且投遞紀錄在第一次嘗試前就寫下了。連續失敗二十次的端點會被停用,而不是繼續被打。

用投遞 id 去重

每次嘗試都帶 `X-Autostud-Delivery`。同一個 id 就是同一個事件:把它當成你後續工作的主鍵。

import crypto from 'node:crypto'

// The header is "t=<unix>,v1=<hex>" and the signed string is "<t>.<raw body>".
// Raw body: parse it AFTER verifying, never re-serialize before.
export function verify(raw_body, header, secret, tolerance = 300) {
  const parts = Object.fromEntries(
    String(header || '').split(',').map((entry) => entry.split('=').map((s) => s.trim()))
  )

  const timestamp = Number(parts.t)
  if (!Number.isFinite(timestamp)) return false
  if (Math.abs(Date.now() / 1000 - timestamp) > tolerance) return false

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${raw_body}`)
    .digest('hex')

  const received = String(parts.v1 || '')
  if (received.length !== expected.length) return false

  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))
}

app.post('/hooks/autostud', express.raw({ type: '*/*' }), (req, res) => {
  const raw = req.body.toString('utf8')

  if (!verify(raw, req.get('X-Autostud-Signature'), process.env.AUTOSTUD_WEBHOOK_SECRET)) {
    return res.status(400).send('bad signature')
  }

  // Deliveries can repeat: deduplicate on this id before doing any work.
  const delivery_id = req.get('X-Autostud-Delivery')
  const event = JSON.parse(raw)

  if (event.event === 'render.completed') {
    console.log(event.data.render_url)
  }

  res.status(200).send('ok')
})
你得到什麼

為什麼是一個呼叫而不是十五個

最難自己重做的部分,正是我們幫你營運的部分。

逐字對齊

每個字都有自己的起訖,所以高亮會落在音節上。以句子為單位的對齊,正是多數自動字幕看起來慢半拍的原因。

116 種樣式,一個字串

從乾淨的廣播字幕到跳動的高亮風格。預設會一併設定字體、外框、顏色與動畫,並依你的畫布縮放。

重點由 AI 挑

第二次處理會讀過逐字稿,標出承載意義的詞。語助詞維持安靜。一個布林值就能關掉。

兩個講者,兩種顏色

講者分離只是一個開關。訪談回來時每個聲音各有顏色,觀眾靜音也知道誰在說話。

和後台同一批物件

用 API 加過字幕的影片,在編輯器裡打開就跟其他影片一樣。手動改一個字、重新算圖、繼續自動化 — 兩條路寫的是同一份文件。

為重送而生

冪等金鑰、有型別的錯誤、測試金鑰、簽章 webhook,還有 30 天的請求紀錄。API 無聊的那一半,也就是凌晨三點會感謝的那一半。

常見問題

開發者真的會寄來的問題

不行,而且是刻意的:API 收的是網址。把影片放在我們伺服器讀得到的地方 — 你的儲存桶、CDN、簽名連結 — 再用 `media_url` 傳過來。從後台上傳的檔案本來就有可用的網址。

目前沒有。字幕是壓進 mp4 的,這正是短影音平台需要的形式。字詞與時間點會存在影片上,所以要另存字幕檔,可以用 API 回傳的資料在你這邊自行轉換。

一次算圖固定 20 點數,不論長度。轉寫與強調處理會像其他 AI 呼叫一樣記錄在你的工作區,`GET /api/v1/usage` 會告訴你某把金鑰這期用了多少。

是幾分鐘,不是幾秒:它跑在 worker 叢集上,不在請求裡。`render.completed` 的存在正是為此 — 請訂閱,而不是一直掛著連線。

可以。用 `restyle_only: true` 加上另一個 `style_preset` 再呼叫一次 `subtitles.generate`:它會重用影片上已存的字詞,不會再轉寫一遍。

Whisper 會自己偵測語言,字幕就用實際說的語言回來 — 不用宣告。偵測到的語言會在回應裡,方便你分支處理。

從你自己的後端輸出上字幕的影片

建立金鑰、跑一次快速開始,第一支上字幕的 mp4 只差幾分鐘。

安全付款
立即使用
隨時取消