貼り付けて、キーを入れて、実行するだけ。疑似コードは一行もありません。
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本です。
ダッシュボード → 設定 → 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"アップロード用エンドポイントはありません。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"
}'`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"
}'`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
}'`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"
}'`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.create | videos:write | 動画プロジェクトを作成し、そのIDを返します。 |
| POST /api/v1/actions/subtitles.generate | videos:execute | 文字起こし・強調・スタイル適用を行い、字幕トラックを保存します。 |
| POST /api/v1/actions/renders.create | renders:execute | ワーカー群にレンダーを投入します。20クレジット。 |
| GET /api/v1/renders?video_id=… | renders:read | ある動画のレンダー一覧(新しい順)。ステータスとURL付き。 |
| POST /api/v1/webhooks | webhooks:write | https エンドポイントを登録し、署名シークレットを一度だけ返します。 |
`style_preset` に1つ渡すだけです。各プリセットがフォント・縁取り・強調色・アニメーションをまとめて決めるので、他に設定するものはありません。
default4 語 · simplebold3 語 · simpleimpact3 語 · focus_on_one_wordbeast1 語 · focus_on_one_wordkaraoke5 語 · focus_on_one_wordkaraoke_fill5 語 · karaokeneon4 語 · progressively_visibleminimal6 語 · simplepop5 語 · progressively_visiblepill5 語 · simplecinematic9 語 · simpleエラーの形はどれも同じです。分岐用の安定した `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"
}
}レンダーは数分かかります。向こうから来させましょう。
`X-Autostud-Signature: t=<unix>,v1=<hex>` は `"<timestamp>.<生のボディ>"` に対する HMAC-SHA256 です。パースする前に、生のボディで検証してください。
約2時間のあいだに5回試行し、配信レコードは1回目の前に書き込まれます。20回連続で失敗したエンドポイントは、叩き続けずに無効化します。
各試行は `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')
})作り直すのが大変な部分こそ、こちらが運用している部分です。
各単語が自分の開始と終了を持つので、ハイライトが音節に乗ります。文単位のタイミングこそ、自動字幕が遅れて見える原因です。
落ち着いた放送用から、跳ねるハイライト系まで。プリセットがフォント・縁取り・色・アニメーションをまとめて、キャンバスに合わせて調整します。
2回目のパスが文字起こしを読み、意味を担う語を印します。つなぎ言葉は静かなまま。真偽値ひとつでオフにできます。
話者分離はフラグひとつ。インタビューは声ごとに色が分かれて返るので、音がなくても誰が話しているか分かります。
API で字幕を付けた動画も、エディタで普通に開けます。単語を手で直して再レンダーし、そのまま自動化を続けられます。両方の経路が同じドキュメントを書きます。
冪等キー、型付きエラー、テストキー、署名付き Webhook、30日分のリクエストログ。APIの地味な半分、つまり深夜3時に効いてくる部分です。
できません。これは意図的で、APIはURLを受け取ります。当社サーバーが読める場所(自社バケット、CDN、署名付きリンク)に置き、`media_url` に渡してください。ダッシュボードからアップロードしたファイルには、そのまま使えるURLがあります。
今はできません。字幕は mp4 に焼き込まれます(ショート動画のプラットフォームが必要とするのはこちらです)。単語とタイミングのリストは動画に保存されるので、別ファイルはAPIの返り値から自前で生成できます。
レンダーは長さに関係なく固定20クレジットです。文字起こしと強調パスは、他のAI呼び出しと同じようにワークスペースに記録され、`GET /api/v1/usage` で期間内の消費を確認できます。
秒ではなく分単位です。リクエスト内ではなくワーカー群で走ります。だからこそ `render.completed` があります。接続を開いたままにせず、購読してください。
はい。`restyle_only: true` と別の `style_preset` で `subtitles.generate` を呼び直すと、動画に保存済みの単語を再利用するので、二重に文字起こしされません。
Whisper が言語を自動判別し、字幕は話されている言語で返ります。宣言は不要です。検出された言語は応答に含まれるので、そこで分岐できます。
どれもブラウザで動き、試すのにアカウントは不要です。
4つの案からお気に入りを選び、磨き上げよう。
実際の画面で、全サイズ・36言語に対応。
ひとつのテーマから10の提案。次のサムネイルを作ろう。
どんなテーマもクイズ動画に
16:9 でもショートでもクイズ動画に
どんなテーマもクイズReelに
縦型のクイズショートを数分で
単語リストを語学動画に
2つの選択肢、画面はまっぷたつ
質問ひとつ、答え10個、難易度4段階
10問、どんどん難しく
名前を言われたら脱落
同じことを考えたら脱落
10個の場面、ひとつのスコア
SからDまで、何でもランク付け
判定が出る前に当てる
指10本からスタート
あなたの線引きはどこ?
あなたの線引きはどこ?
ツイートやXの投稿を動画に変換
どんな曲もカラオケ動画に
Redditのスレッドをショート動画に
表計算データをランキング動画に
TikTokのコメント欄を曲の動画に変える
Instagramのコメント欄を曲の動画に変える
Xの投稿へのリプライを曲の動画に変える
AIでバズるフルーツクイズ動画を作成
声を変えずに音声を速くする
複数の音声ファイルを1つにまとめる
動画からタイムスタンプ付きのチャプターを作成
どんな画像からも正確なAIプロンプトを
顔を出さずにAI動画を
物語をアニメ動画に
質問、カウントダウン、次の質問
最後まで見られる台本を
インスタのカルーセルとTikTokのスライドショー
動画に自然なナレーションを
動画の案内役をつくる
TikTok向けフルーツカット動画を3Dで