Dodaj napisy do każdego wideo
trzema wywołaniami API
Wyślij URL wideo, odbierz mp4 z napisami wypalonymi słowo po słowie. Whisper synchronizuje każde słowo, przebieg AI wybiera te do podkreślenia, a render idzie na naszą flotę workerów.
POSThttps://autostud.ai/api/v1/actions/subtitles.generateCała ścieżka w jednym pliku
Wklej, ustaw klucz, uruchom. Nic tu nie jest pseudokodem.
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)Adres bazowy: https://autostud.ai/api/v1 — uwierzytelnianie przez `Authorization: Bearer sk_live_…`. Klucz `sk_test_` przechodzi dokładnie tę samą ścieżkę i zatrzymuje się przed wydaniem czegokolwiek.
Co naprawdę musisz zrobić
Sześć kroków, cztery z nich to jedno żądanie.
- 1
Utwórz klucz API
Panel, Ustawienia, Klucze API. Wybierz preset „Automation”, jeśli nie chcesz ustawiać scope’ów ręcznie: obejmuje wideo, rendery i pliki. Sekret pokazuje się raz. `sk_live_` wydaje, `sk_test_` waliduje całe żądanie i zatrzymuje się przed zapisem.
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
Umieść wideo pod adresem URL
Nie ma endpointu do wysyłki pliku: API czyta URL. Twój bucket, twoje CDN, podpisany link — cokolwiek nasze serwery pobiorą. Zapis w bibliotece przestrzeni jest opcjonalny i niczego nie zmienia.
# 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
Utwórz projekt wideo
`videos.create` zwraca `video_id`, do którego podpina się reszta. Wyślij `Idempotency-Key`, a ponowione żądanie zwróci pierwszą odpowiedź zamiast tworzyć drugi projekt.
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
Dodaj napisy
`subtitles.generate` robi całą robotę po stronie serwera: Whisper transkrybuje z dokładnością do słowa, przebieg AI zaznacza słowa do podkreślenia, a jeden z 116 stylów zostaje nałożony. W odpowiedzi masz liczbę słów, dokładny czas i wykryty język.
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
Zakolejkuj render
`renders.create` wrzuca zadanie na flotę workerów i od razu odpowiada `render_id`. Render kosztuje 20 kredytów, niezależnie od długości.
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
Odbierz mp4
Subskrybuj `render.completed`, a gotowy URL przyjdzie do ciebie podpisany. Jeśli wolisz odpytywać, wylistuj rendery wideo i czytaj `render_status`, aż pokaże `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.
Wszystkie wywołania z tej strony
Scope to to, co musi mieć klucz, a nie to, co wysyłasz.
| Wywołanie | Scope | Co robi |
|---|---|---|
| GET /api/v1 | - | Discovery: co potrafi ten klucz, jakie ma limity i zużycie. |
| POST /api/v1/actions/videos.create | videos:write | Tworzy projekt wideo i zwraca jego identyfikator. |
| POST /api/v1/actions/subtitles.generate | videos:execute | Transkrybuje, podkreśla, styluje i zapisuje ścieżkę napisów. |
| POST /api/v1/actions/renders.create | renders:execute | Kolejkuje render na flocie workerów. 20 kredytów. |
| GET /api/v1/renders?video_id=… | renders:read | Rendery danego wideo, od najnowszego, ze statusem i URL-em. |
| POST /api/v1/webhooks | webhooks:write | Rejestruje endpoint https i raz zwraca jego sekret podpisujący. |
Dostępne style
Podaj jeden w `style_preset`. Każdy ustawia naraz font, obrys, kolor akcentu i animację — nie ma nic więcej do konfigurowania.
default4 słowa · simplebold3 słowa · simpleimpact3 słowa · focus_on_one_wordbeast1 słowa · focus_on_one_wordkaraoke5 słowa · focus_on_one_wordkaraoke_fill5 słowa · karaokeneon4 słowa · progressively_visibleminimal6 słowa · simplepop5 słowa · progressively_visiblepill5 słowa · simplecinematic9 słowa · simpleCo warto wiedzieć przed kodowaniem
- Limity są per klucz i wracają w nagłówkach: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `Retry-After` przy 429.
- `Idempotency-Key` przy każdym POST czyni ponowienie bezpiecznym przez 24 godziny; pierwsza odpowiedź wraca bez zmian.
- Klucz `sk_test_` przechodzi uwierzytelnianie, scope’y, limity i walidację, po czym odpowiada `simulated: true` bez zapisu i bez wydatku.
- Błędy są typowane: `invalid_request`, `insufficient_credits`, `rate_limit_exceeded`, `upstream_error` — rozgałęziaj po kodzie, nigdy po treści.
Kiedy się nie uda
Każdy błąd ma ten sam kształt: stabilny `code` do rozgałęzień, `hint` wskazujący wywołanie, które to naprawi, i `request_id` do zacytowania. Pełny słownik jest na /docs/api/errors.
| Kod | Co oznacza |
|---|---|
| 401 missing_credentials | Brak klucza w żądaniu albo klucz nieznany. |
| 403 insufficient_scope | Kluczowi brakuje scope; `details.required_scopes` go nazywa. |
| 422 validation_failed | Pole jest niepoprawne; `details.issues` wylicza każde z nich. |
| 402 insufficient_credits | Za mało kredytów na render. Doładuj albo użyj klucza testowego. |
| 429 rate_limit_exceeded | Za dużo wywołań. Odczekaj `Retry-After` sekund i ponów. |
| 502 upstream_error | Dostawca, od którego zależymy, zawiódł. Ponów z backoffem. |
{
"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"
}
}Przestań odpytywać
Render trwa minuty. Niech sam do ciebie przyjdzie.
Podpisane, do sprawdzenia w dziesięciu linijkach
`X-Autostud-Signature: t=<unix>,v1=<hex>` to HMAC-SHA256 z `"<timestamp>.<surowe ciało>"`. Weryfikuj na surowym ciele, zanim je sparsujesz.
Ponawiane za ciebie
Pięć prób w ciągu około dwóch godzin, a wiersz dostawy zapisuje się przed pierwszą. Endpoint, który zawiedzie dwadzieścia razy z rzędu, zostaje wyłączony, a nie zasypywany.
Deduplikuj po id dostawy
Każda próba niesie `X-Autostud-Delivery`. To samo id to to samo zdarzenie: traktuj je jak klucz główny pracy, którą uruchamiasz.
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')
})Dlaczego to jedno wywołanie, a nie piętnaście
Trudne do odtworzenia kawałki to te, które my utrzymujemy.
Synchronizacja co do słowa
Każde słowo ma własny początek i koniec, więc podświetlenie trafia w sylabę. Synchronizacja zdaniami sprawia, że większość automatycznych napisów wydaje się spóźniona.
116 stylów, jeden string
Od czystych napisów telewizyjnych po skaczący, podświetlany look. Preset ustawia font, obrys, kolor i animację razem, w skali twojego kadru.
AI wybiera akcenty
Drugi przebieg czyta transkrypcję i zaznacza słowa niosące sens. Wypełniacze zostają spokojne. Wyłączasz to jednym booleanem.
Dwa głosy, dwa kolory
Diaryzacja to flaga. Wywiad wraca z każdym głosem w swoim kolorze, więc widz wie, kto mówi, nawet bez dźwięku.
Te same obiekty co w panelu
Wideo otytułowane przez API otwiera się w edytorze jak każde inne. Popraw słowo ręcznie, zrenderuj ponownie, automatyzuj dalej — obie drogi piszą ten sam dokument.
Zbudowane pod ponowienia
Klucze idempotencji, typowane błędy, klucze testowe, podpisane webhooki i 30-dniowy log żądań. Nudna połowa API — czyli ta, którą czuć o trzeciej w nocy.
Pytania, które naprawdę dostajemy od programistów
Nie i jest to celowe: API przyjmuje URL. Postaw wideo tam, gdzie nasze serwery je odczytają — twój bucket, CDN, podpisany link — i podaj je w `media_url`. Pliki wgrane z panelu mają już gotowy URL.
Dziś nie. Napisy są wypalane w mp4, bo tego wymagają platformy krótkiego wideo. Lista słów z czasami zostaje zapisana na wideo, więc osobny plik to przekształcenie, które zrobisz u siebie z tego, co zwraca API.
Render to 20 kredytów, na stałe, niezależnie od długości. Transkrypcja i przebieg podkreśleń są logowane w twojej przestrzeni jak każde inne wywołanie AI, a `GET /api/v1/usage` pokazuje, ile klucz wydał w okresie.
Minuty, nie sekundy: idzie na flotę workerów, nie do żądania. Dokładnie po to jest `render.completed` — subskrybuj zamiast trzymać otwarte połączenie.
Tak. Wywołaj `subtitles.generate` ponownie z `restyle_only: true` i innym `style_preset`: użyje słów już zapisanych na wideo, więc nic nie jest transkrybowane dwa razy.
Whisper sam wykrywa język, a napisy wracają w tym, którym się mówi — niczego nie deklarujesz. Wykryty język jest w odpowiedzi, jeśli chcesz się na nim rozgałęzić.
Co możesz wywołać
Zleć render, odbierz webhook zamiast odpytywać i pobierz mp4.
Przeczytaj przewodnikTekst na wideo, sceny faceless i wydłużanie ujęć prosto z Twojego backendu.
Przeczytaj przewodnikGeneruj, zmieniaj styl, kadruj i usuwaj tło na dużą skalę.
Przeczytaj przewodnikSynteza mowy na dowolnej warstwie, dopasowanie Whisper i piosenki AI.
Przeczytaj przewodnikZaplanuj gotowe wideo i odczytaj kalendarz.
Przeczytaj przewodnikWięcej darmowych narzędzi
Wszystkie działają w przeglądarce, bez konta do wypróbowania.
Generator Wideo Quizów TikTok
Narzędzie na żywoZamień dowolny temat w wideo quiz
Generator Wideo Quizów YouTube
Narzędzie na żywoWideo quizy w 16:9 albo w Shorts
Generator Wideo Quizów Instagram Reels
Narzędzie na żywoQuizowe Reels z dowolnego tematu
Generator Wideo Quizów YouTube Shorts
Narzędzie na żywoPionowe quizowe Shorts w kilka minut
Generator Wideo Quizów Językowych
Narzędzie na żywoZamień listę słówek w wideo do nauki języka
Generator Wideo Co Wolisz
Narzędzie na żywoDwie opcje, podzielony ekran
Generator Wideo Quizów z Poziomami
Narzędzie na żywoJedno pytanie, dziesięć odpowiedzi, cztery poziomy
Generator Wideo Quizów Poziomy
Narzędzie na żywoDziesięć pytań, każde trudniejsze
Generator Wideo Eliminacja po Imieniu
Narzędzie na żywoJeśli powiem twoje imię, odpadasz
Generator Wideo Jeśli Myślisz To Samo
Narzędzie na żywoPomyślałeś to samo? Odpadasz
Generator Wideo Rizz Quiz Challenge
Narzędzie na żywoDziesięć sytuacji, jeden wynik
Generator Wideo Tier List
Narzędzie na żywoUszereguj wszystko, od S do D
Generator Wideo Red Flag Green Flag
Narzędzie na żywoZgadnij, zanim padnie wyrok
Generator Wideo Opuść Palec
Narzędzie na żywoDziesięć palców w górę. Liczymy.
Generator Wideo Czy Twój Chłopak Może
Narzędzie na żywoGdzie jest twoja granica?
Generator Wideo Czy Twoja Dziewczyna Może
Narzędzie na żywoGdzie jest twoja granica?
Tweet na Wideo
Narzędzie na żywoZamień tweety w wideo
YouTube na Wideo Karaoke
Narzędzie na żywoZamień utwór w wideo karaoke
Post Reddit na Wideo
Narzędzie na żywoZamień wątek z Reddita w shorta
CSV na Wideo Ranking
Narzędzie na żywoZamień arkusz w wideo z rankingiem
Komentarze TikTok na Wideo Piosenkę
Narzędzie na żywoZamień komentarze z TikToka w wideo piosenkę
Filmy AI Owoce
Twórz wirusowe filmy o owocach z AI
Przyspieszanie Audio
Narzędzie na żywoPrzyspiesz audio bez zmiany głosu
Łączenie plików audio
Narzędzie na żywoPołącz kilka plików audio w jeden
Wypuszczaj wideo z napisami ze swojego backendu
Utwórz klucz, uruchom quickstart — pierwsze mp4 z napisami dzieli od ciebie kilka minut.