REST API|動画字幕 API

どんな動画にも字幕を
APIコール3回で

動画のURLを送るだけで、単語単位の字幕を焼き込んだ mp4 が返ってきます。Whisper が各単語のタイミングを取り、AI が強調する語を選び、レンダリングは当社のワーカー群で走ります。

POSThttps://autostud.ai/api/v1/actions/subtitles.generate
クイックスタート

全工程を1ファイルで

貼り付けて、キーを入れて、実行するだけ。疑似コードは一行もありません。

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)

ベースURL: https://autostud.ai/api/v1 — 認証は `Authorization: Bearer sk_live_…`。`sk_test_` キーは同じ経路をすべて通ったうえで、消費の直前で止まります。

ステップ

実際にやることはこれだけ

6ステップ。うち4つはリクエスト1本です。

  1. 1

    APIキーを作る

    ダッシュボード → 設定 → APIキー。スコープを自分で選ばないなら「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

    動画をURLに置く

    アップロード用エンドポイントはありません。APIが読むのはURLです。自社バケット、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` を付ければ、再送しても2つ目のプロジェクトは作られず最初の応答が返ります。

    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種類のスタイルから1つを適用。応答には単語数・正確な尺・検出言語が入ります。

    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` がワーカー群にジョブを載せ、即座に `render_id` を返します。1レンダーは長さに関係なく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` を購読すれば、完成URLが署名付きで届きます。取りに行きたい場合は、その動画のレンダー一覧を取得して `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.
リファレンス

このページで使う全コール

スコープは「キーが持つべき権限」であって、送る値ではありません。

コールスコープ何をするか
GET /api/v1-ディスカバリー:このキーで何ができるか、制限、消費量。
POST /api/v1/actions/videos.createvideos:write動画プロジェクトを作成し、そのIDを返します。
POST /api/v1/actions/subtitles.generatevideos:execute文字起こし・強調・スタイル適用を行い、字幕トラックを保存します。
POST /api/v1/actions/renders.createrenders:executeワーカー群にレンダーを投入します。20クレジット。
GET /api/v1/renders?video_id=…renders:readある動画のレンダー一覧(新しい順)。ステータスとURL付き。
POST /api/v1/webhookswebhooks:writehttps エンドポイントを登録し、署名シークレットを一度だけ返します。

スタイルプリセット

`style_preset` に1つ渡すだけです。各プリセットがフォント・縁取り・強調色・アニメーションをまとめて決めるので、他に設定するものはありません。

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_` キーは認証・スコープ・制限・バリデーションまで実行し、書き込みも消費もせずに `simulated: true` を返します。
  • エラーは型付きです:`invalid_request`、`insufficient_credits`、`rate_limit_exceeded`、`upstream_error` — メッセージではなくコードで分岐してください。

失敗したとき

エラーの形はどれも同じです。分岐用の安定した `code`、直し方の呼び出しを名指しする `hint`、そして問い合わせ用の `request_id`。全コードの一覧は /docs/api/errors にあります。

コード意味
401 missing_credentialsリクエストにキーがない、または知らないキーです。
403 insufficient_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

ポーリングをやめる

レンダーは数分かかります。向こうから来させましょう。

署名付き、検証は10行

`X-Autostud-Signature: t=<unix>,v1=<hex>` は `"<timestamp>.<生のボディ>"` に対する HMAC-SHA256 です。パースする前に、生のボディで検証してください。

再送はこちらで

約2時間のあいだに5回試行し、配信レコードは1回目の前に書き込まれます。20回連続で失敗したエンドポイントは、叩き続けずに無効化します。

配信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')
})
得られるもの

なぜ15回ではなく1回で済むのか

作り直すのが大変な部分こそ、こちらが運用している部分です。

単語単位のタイミング

各単語が自分の開始と終了を持つので、ハイライトが音節に乗ります。文単位のタイミングこそ、自動字幕が遅れて見える原因です。

116スタイル、文字列ひとつ

落ち着いた放送用から、跳ねるハイライト系まで。プリセットがフォント・縁取り・色・アニメーションをまとめて、キャンバスに合わせて調整します。

強調はAIが選ぶ

2回目のパスが文字起こしを読み、意味を担う語を印します。つなぎ言葉は静かなまま。真偽値ひとつでオフにできます。

2人の話者、2色

話者分離はフラグひとつ。インタビューは声ごとに色が分かれて返るので、音がなくても誰が話しているか分かります。

ダッシュボードと同じオブジェクト

API で字幕を付けた動画も、エディタで普通に開けます。単語を手で直して再レンダーし、そのまま自動化を続けられます。両方の経路が同じドキュメントを書きます。

再試行前提の設計

冪等キー、型付きエラー、テストキー、署名付き Webhook、30日分のリクエストログ。APIの地味な半分、つまり深夜3時に効いてくる部分です。

FAQ

開発者から実際に届く質問

できません。これは意図的で、APIはURLを受け取ります。当社サーバーが読める場所(自社バケット、CDN、署名付きリンク)に置き、`media_url` に渡してください。ダッシュボードからアップロードしたファイルには、そのまま使えるURLがあります。

今はできません。字幕は mp4 に焼き込まれます(ショート動画のプラットフォームが必要とするのはこちらです)。単語とタイミングのリストは動画に保存されるので、別ファイルはAPIの返り値から自前で生成できます。

レンダーは長さに関係なく固定20クレジットです。文字起こしと強調パスは、他のAI呼び出しと同じようにワークスペースに記録され、`GET /api/v1/usage` で期間内の消費を確認できます。

秒ではなく分単位です。リクエスト内ではなくワーカー群で走ります。だからこそ `render.completed` があります。接続を開いたままにせず、購読してください。

はい。`restyle_only: true` と別の `style_preset` で `subtitles.generate` を呼び直すと、動画に保存済みの単語を再利用するので、二重に文字起こしされません。

Whisper が言語を自動判別し、字幕は話されている言語で返ります。宣言は不要です。検出された言語は応答に含まれるので、そこで分岐できます。

ほかの無料ツール

どれもブラウザで動き、試すのにアカウントは不要です。

TikTok クイズ動画メーカー

実際に動くツール

どんなテーマもクイズ動画に

YouTube クイズ動画メーカー

実際に動くツール

16:9 でもショートでもクイズ動画に

Instagram Reels クイズ動画メーカー

実際に動くツール

どんなテーマもクイズReelに

YouTube Shorts クイズ動画メーカー

実際に動くツール

縦型のクイズショートを数分で

語学クイズ動画メーカー

実際に動くツール

単語リストを語学動画に

どっちを選ぶ動画メーカー

実際に動くツール

2つの選択肢、画面はまっぷたつ

難易度別クイズ動画メーカー

実際に動くツール

質問ひとつ、答え10個、難易度4段階

レベル別クイズ動画メーカー

実際に動くツール

10問、どんどん難しく

名前で脱落動画メーカー

実際に動くツール

名前を言われたら脱落

同じ答えで脱落動画メーカー

実際に動くツール

同じことを考えたら脱落

Rizz クイズチャレンジ動画メーカー

実際に動くツール

10個の場面、ひとつのスコア

Tier List 動画メーカー

実際に動くツール

SからDまで、何でもランク付け

Red Flag Green Flag 動画メーカー

実際に動くツール

判定が出る前に当てる

指を下げる動画メーカー

実際に動くツール

指10本からスタート

彼氏はしていい?動画メーカー

実際に動くツール

あなたの線引きはどこ?

彼女はしていい?動画メーカー

実際に動くツール

あなたの線引きはどこ?

ツイートを動画に

実際に動くツール

ツイートやXの投稿を動画に変換

YouTubeをカラオケ動画に

実際に動くツール

どんな曲もカラオケ動画に

Reddit投稿を動画に

実際に動くツール

Redditのスレッドをショート動画に

CSVをランキング動画に

実際に動くツール

表計算データをランキング動画に

TikTokコメントを楽曲動画に

実際に動くツール

TikTokのコメント欄を曲の動画に変える

AIフルーツ動画

AIでバズるフルーツクイズ動画を作成

音声速度チェンジャー

実際に動くツール

声を変えずに音声を速くする

音声ファイル結合

実際に動くツール

複数の音声ファイルを1つにまとめる

自社のバックエンドから字幕付き動画を出す

キーを作ってクイックスタートを実行すれば、最初の字幕付き mp4 まで数分です。

安全な決済
すぐに利用可能
いつでも解約可能