auto stud
API REST|API de Subtítulos de Vídeo

Subtitula cualquier vídeo
con tres llamadas API

Envía la URL de un vídeo y recibe un mp4 con subtítulos incrustados palabra por palabra. Whisper ajusta cada palabra, una pasada de IA elige las que se resaltan y el render corre en nuestra flota de workers.

POSThttps://autostud.ai/api/v1/actions/subtitles.generate
Inicio rápido

Todo el recorrido, en un solo archivo

Pégalo, pon tu clave, ejecútalo. Aquí no hay pseudocódigo.

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 base: https://autostud.ai/api/v1 — autentica con `Authorization: Bearer sk_live_…`. Una clave `sk_test_` recorre exactamente el mismo camino y se detiene antes de gastar nada.

Paso a paso

Lo que realmente tienes que hacer

Seis pasos, cuatro de ellos una sola petición.

  1. 1

    Crear una clave API

    Panel, Ajustes, Claves API. Elige el preajuste «Automation» si no quieres seleccionar scopes a mano: cubre vídeos, renders y archivos. El secreto se muestra una vez. `sk_live_` gasta, `sk_test_` valida toda la petición y se detiene antes de escribir.

    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

    Poner el vídeo tras una URL

    No hay endpoint de subida: la API lee una URL. Tu bucket, tu CDN, un enlace firmado — cualquier cosa que nuestros servidores puedan descargar. Registrarlo en la biblioteca del espacio es opcional y no cambia el flujo.

    # 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

    Crear el proyecto de vídeo

    `videos.create` devuelve el `video_id` del que cuelga todo lo demás. Envía un `Idempotency-Key` y una petición reintentada devuelve la primera respuesta en lugar de crear un segundo proyecto.

    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

    Subtitularlo

    `subtitles.generate` hace todo el trabajo en el servidor: Whisper transcribe con tiempos por palabra, una pasada de IA marca las palabras a resaltar y se aplica uno de los 116 estilos. Responde con el número de palabras, la duración exacta y el idioma detectado.

    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

    Encolar el render

    `renders.create` pone el trabajo en la flota de workers y responde al momento con el `render_id`. Un render cuesta 20 créditos, sea cual sea la duración.

    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

    Recoger el mp4

    Suscríbete a `render.completed` y la URL final llega firmada. Si prefieres consultar tú, lista los renders del vídeo y lee `render_status` hasta que diga `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.
Referencia

Todas las llamadas de esta página

Los scopes son lo que debe llevar la clave, no lo que envías.

LlamadaScopeQué hace
GET /api/v1-Descubrimiento: qué puede hacer la clave, sus límites y su consumo.
POST /api/v1/actions/videos.createvideos:writeCrea el proyecto de vídeo y devuelve su identificador.
POST /api/v1/actions/subtitles.generatevideos:executeTranscribe, resalta, aplica estilo y guarda la pista de subtítulos.
POST /api/v1/actions/renders.createrenders:executeEncola el render en la flota de workers. 20 créditos.
GET /api/v1/renders?video_id=…renders:readLos renders de un vídeo, del más reciente al más antiguo, con estado y URL.
POST /api/v1/webhookswebhooks:writeRegistra un endpoint https y devuelve su secreto de firma, una vez.

Estilos disponibles

Pasa uno en `style_preset`. Cada uno fija a la vez la tipografía, el contorno, el color de acento y la animación — no hay nada más que configurar.

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

Lo que conviene saber antes de programar

  • Los límites de peticiones son por clave y vienen en cabeceras: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `Retry-After` en un 429.
  • `Idempotency-Key` en cualquier POST hace seguro un reintento durante 24 horas; la primera respuesta se repite tal cual.
  • Una clave `sk_test_` ejercita autenticación, scopes, límites y validación, y luego responde `simulated: true` sin escribir ni gastar.
  • Los errores son tipados: `invalid_request`, `insufficient_credits`, `rate_limit_exceeded`, `upstream_error` — ramifica por el código, nunca por el mensaje.

Cuando falla

Todos los fallos tienen la misma forma: un `code` estable sobre el que ramificar, un `hint` que nombra la llamada que lo arregla y un `request_id` que citar. El vocabulario completo está en /docs/api/errors.

CódigoQué significa
401 missing_credentialsNo hay clave en la petición, o no la reconocemos.
403 insufficient_scopeA la clave le falta un scope; `details.required_scopes` lo nombra.
422 validation_failedAlgún campo es inválido; `details.issues` los lista todos.
402 insufficient_creditsNo hay créditos suficientes para el render. Recarga, o usa una clave de prueba.
429 rate_limit_exceededDemasiadas llamadas. Espera `Retry-After` segundos y reintenta.
502 upstream_errorUn proveedor del que dependemos ha fallado. Reintenta con backoff.
{
  "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"
  }
}

Códigos de error

Webhooks

Deja de hacer polling

Un render tarda minutos. Deja que llegue solo.

Firmados y verificables en diez líneas

`X-Autostud-Signature: t=<unix>,v1=<hex>` es un HMAC-SHA256 sobre `"<timestamp>.<cuerpo crudo>"`. Verifica contra el cuerpo crudo, antes de parsearlo.

Reintentados por ti

Cinco intentos a lo largo de unas dos horas, con la fila de entrega escrita antes del primero. Un endpoint que falla veinte veces seguidas se desactiva en vez de machacarse.

Deduplica por el id de entrega

Cada intento lleva `X-Autostud-Delivery`. Mismo id, mismo evento: trátalo como la clave primaria del trabajo que dispares.

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')
})
Qué obtienes

Por qué es una llamada y no quince

Las piezas difíciles de rehacer son las que operamos nosotros.

Ajuste por palabra

Cada palabra lleva su inicio y su final, así que el resaltado cae en la sílaba. El ajuste por frase es lo que hace que casi todos los subtítulos automáticos parezcan tardíos.

116 estilos, una cadena

Del subtítulo sobrio de televisión al estilo saltarín resaltado. El preajuste fija tipografía, contorno, color y animación juntos, escalados a tu lienzo.

La IA elige los acentos

Una segunda pasada lee la transcripción y marca las palabras que llevan el sentido. Las muletillas se quedan quietas. Un booleano la desactiva.

Dos voces, dos colores

La diarización es un flag. Una entrevista vuelve con cada voz en su color, y el espectador sabe quién habla sin sonido.

Los mismos objetos que el panel

Un vídeo subtitulado por la API se abre en el editor como cualquier otro. Corrige una palabra a mano, vuelve a renderizar, sigue automatizando: los dos caminos escriben el mismo documento.

Pensada para reintentos

Claves de idempotencia, errores tipados, claves de prueba, webhooks firmados y un registro de peticiones de 30 días. La mitad aburrida de una API, que es la que se nota a las 3 de la mañana.

FAQ

Las preguntas que de verdad nos llegan

No, y es a propósito: la API toma una URL. Aloja el vídeo donde nuestros servidores puedan leerlo — tu bucket, un CDN, un enlace firmado — y pásalo en `media_url`. Los archivos subidos desde el panel ya tienen una URL utilizable.

Hoy no. Los subtítulos se incrustan en el mp4, que es lo que piden las plataformas de formato corto. La lista de palabras con sus tiempos queda guardada en el vídeo, así que un archivo aparte es una transformación que puedes hacer tú con lo que devuelve la API.

Un render son 20 créditos, fijos, dure lo que dure. La transcripción y la pasada de énfasis se registran en tu espacio como cualquier otra llamada de IA, y `GET /api/v1/usage` informa de lo que ha gastado una clave en el periodo.

Minutos, no segundos: corre en una flota de workers, no dentro de la petición. Justo para eso existe `render.completed` — suscríbete en lugar de mantener una conexión abierta.

Sí. Llama otra vez a `subtitles.generate` con `restyle_only: true` y otro `style_preset`: reutiliza las palabras ya guardadas en el vídeo, así que nada se transcribe dos veces.

Whisper detecta el idioma por su cuenta y los subtítulos salen en el que se habla — no hay que declarar nada. El idioma detectado viene en la respuesta por si quieres ramificar.

Más herramientas gratis

Todas funcionan en el navegador, sin cuenta para probarlas.

Generador de Vídeo Quiz TikTok

Herramienta en vivo

Convierte cualquier tema en un vídeo quiz

Generador de Vídeo Quiz YouTube

Herramienta en vivo

Vídeos quiz en 16:9 o en Shorts

Generador de Vídeo Quiz Instagram Reels

Herramienta en vivo

Reels de quiz a partir de cualquier tema

Generador de Vídeo Quiz YouTube Shorts

Herramienta en vivo

Shorts de quiz verticales en minutos

Generador de Vídeo Quiz de Idiomas

Herramienta en vivo

Convierte una lista de palabras en un vídeo de idiomas

Generador de Vídeos Qué Prefieres

Herramienta en vivo

Dos opciones, una pantalla partida

Generador de Vídeos Quiz por Niveles

Herramienta en vivo

Una pregunta, diez respuestas, cuatro niveles

Generador de Vídeo Quiz Niveles

Herramienta en vivo

Diez preguntas, cada una más difícil

Generador de Vídeos de Eliminación por Nombre

Herramienta en vivo

Si digo tu nombre, estás fuera

Generador de Vídeos Si Piensas Lo Mismo

Herramienta en vivo

¿Pensaste lo mismo? Estás fuera

Generador de Vídeos Rizz Quiz Challenge

Herramienta en vivo

Diez situaciones, un marcador

Generador de Vídeos Tier List

Herramienta en vivo

Clasifica todo, de S a D

Generador de Vídeos Red Flag Green Flag

Herramienta en vivo

Adivina antes del veredicto

Generador de Vídeos Baja un Dedo

Herramienta en vivo

Diez dedos arriba. A contar.

Generador de Vídeos Tu Novio Puede

Herramienta en vivo

¿Dónde está tu límite?

Generador de Vídeos Tu Novia Puede

Herramienta en vivo

¿Dónde está tu límite?

Tweet a Video

Herramienta en vivo

Convierte tweets en videos

YouTube a Vídeo Karaoke

Herramienta en vivo

Convierte un tema en vídeo karaoke

Post de Reddit a Vídeo

Herramienta en vivo

Convierte un hilo de Reddit en un short

CSV a Vídeo Ranking

Herramienta en vivo

Convierte una hoja de cálculo en un vídeo de ranking

Comentarios TikTok a Vídeo Canción

Herramienta en vivo

Convierte los comentarios de TikTok en un vídeo canción

Vídeos IA Frutas

Crea vídeos de frutas virales con IA

Acelerador de Audio

Herramienta en vivo

Acelera un audio sin cambiar la voz

Unir Audios

Herramienta en vivo

Combina varios archivos de audio en uno

Publica vídeo subtitulado desde tu propio backend

Crea una clave, ejecuta el quickstart y el primer mp4 subtitulado está a unos minutos.

Pagos seguros
Acceso instantáneo
Cancela cuando quieras