# 1. exchange client credentials for a token (valid 1 hour)
curl -X POST https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials"
# 2. upload the video once - YouTube, Drive, S3, Vimeo or direct URL
curl -X POST https://api.rask.ai/api/library/v1/media/link \
-H "Authorization: Bearer $TOKEN" \
-d '{"link": "https://youtu.be/...", "name": "Q3 launch"}'
# 3. one project per target language - they run in parallel
for lang in es-mx de-de ja-jp pt-br; do
curl -X POST https://api.rask.ai/v2/projects \
-H "Authorization: Bearer $TOKEN" \
-d "{\"video_id\": \"$VIDEO_ID\", \"dst_lang\": \"$lang\"}"
done# Poll each project until merging_done, then collect the files.
while :; do
curl -s https://api.rask.ai/v2/projects/$ID \
-H "Authorization: Bearer $TOKEN" \
| jq '{status, translated_video, translation_srt_path}'
sleep 10
done



Envía un archivo como datos de formulario multipart o publica un enlace de YouTube, Google Drive, S3, Vimeo o cualquier URL de descarga directa. Obtendrás un ID de contenido multimedia y los metadatos técnicos antes de gastar nada.
Pasa el ID del medio como video_id y un idioma de destino. Crea un proyecto para cada idioma que necesites a partir de la misma carga, con tu propia transcripción o un glosario si lo tienes.
Lee el estado hasta que llegue a merging_done; luego, descarga el video traducido y los archivos de subtítulos para ese idioma.
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio
from rask_sdk import clients, enums, schemas
TARGETS = ["es-mx", "de-de", "ja-jp", "pt-br"]
async def translate(client, video_id, lang):
job = await client.create_project(
data=schemas.ProjectCreate(video_id=video_id, dst_lang=lang))
while job.status is not enums.ProjectStatus.MERGING_DONE:
await asyncio.sleep(10)
job = await client.get_project(project_id=job.id)
return job
async def main():
client = clients.RaskSDKClient(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
video = await client.create_media_link(
data=schemas.MediaCreateLink(link="https://youtu.be/..."))
while video.status is not enums.MediaStatus.READY:
await asyncio.sleep(5)
video = await client.get_media(media_id=video.id)
jobs = await asyncio.gather(*(translate(client, video.id, l) for l in TARGETS))
for j in jobs:
print(j.dst_lang, j.translated_video, j.translation_srt_path)
asyncio.run(main())import time, requests
AUTH = "https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token"
API = "https://api.rask.ai"
token = requests.post(AUTH, auth=(CLIENT_ID, CLIENT_SECRET),
data={"grant_type": "client_credentials"}).json()["access_token"]
h = {"Authorization": f"Bearer {token}"}
video = requests.post(f"{API}/api/library/v1/media/link", headers=h,
json={"link": "https://youtu.be/..."}).json()
while video["status"] != "ready":
time.sleep(5)
video = requests.get(f"{API}/api/library/v1/media/{video['id']}", headers=h).json()
ids = [requests.post(f"{API}/v2/projects", headers=h,
json={"video_id": video["id"], "dst_lang": lang}).json()["id"]
for lang in ["es-mx", "de-de", "ja-jp", "pt-br"]]
for pid in ids:
while (p := requests.get(f"{API}/v2/projects/{pid}", headers=h).json())["status"] != "merging_done":
time.sleep(10)
print(p["dst_lang"], p["translated_video"], p["translation_vtt_path"])// no dependencies, Node 18+ global fetch
const API = 'https://api.rask.ai';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const auth = await fetch('https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token', {
method: 'POST',
headers: { Authorization: 'Basic ' + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`) },
body: new URLSearchParams({ grant_type: 'client_credentials' }),
}).then((r) => r.json());
const h = { Authorization: `Bearer ${auth.access_token}`, 'Content-Type': 'application/json' };
const get = (path) => fetch(API + path, { headers: h }).then((r) => r.json());
const post = (path, body) => fetch(API + path, { method: 'POST', headers: h, body: JSON.stringify(body) }).then((r) => r.json());
let video = await post('/api/library/v1/media/link', { link: 'https://youtu.be/...' });
while (video.status !== 'ready') { await sleep(5000); video = await get(`/api/library/v1/media/${video.id}`); }
const results = await Promise.all(['es-mx', 'de-de', 'ja-jp', 'pt-br'].map(async (dst_lang) => {
let p = await post('/v2/projects', { video_id: video.id, dst_lang });
while (p.status !== 'merging_done') { await sleep(10000); p = await get(`/v2/projects/${p.id}`); }
return p;
}));
results.forEach((p) => console.log(p.dst_lang, p.translated_video, p.translation_srt_path));<?php
use GuzzleHttp\Client;
$http = new Client(['base_uri' => 'https://api.rask.ai']);
$json = fn($r) => json_decode($r->getBody(), true);
$auth = $json((new Client)->post('https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token',
['auth' => [$clientId, $clientSecret], 'form_params' => ['grant_type' => 'client_credentials']]));
$h = ['Authorization' => 'Bearer ' . $auth['access_token']];
$video = $json($http->post('/api/library/v1/media/link',
['headers' => $h, 'json' => ['link' => 'https://youtu.be/...']]));
while ($video['status'] !== 'ready') {
sleep(5);
$video = $json($http->get("/api/library/v1/media/{$video['id']}", ['headers' => $h]));
}
foreach (['es-mx', 'de-de', 'ja-jp', 'pt-br'] as $lang) {
$p = $json($http->post('/v2/projects', ['headers' => $h,
'json' => ['video_id' => $video['id'], 'dst_lang' => $lang]]));
while ($p['status'] !== 'merging_done') {
sleep(10);
$p = $json($http->get("/v2/projects/{$p['id']}", ['headers' => $h]));
}
echo $lang, ' ', $p['translation_srt_path'], PHP_EOL;
}<?php
use GuzzleHttp\Client;
$http = new Client(['base_uri' => 'https://api.rask.ai']);
$auth = json_decode((new Client)->post(
'https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token',
['auth' => [$clientId, $clientSecret],
'form_params' => ['grant_type' => 'client_credentials']]
)->getBody(), true);
$h = ['Authorization' => 'Bearer ' . $auth['access_token']];
$media = json_decode($http->post('/api/library/v1/media/link',
['headers' => $h, 'json' => ['link' => 'https://youtu.be/...']])->getBody(), true);
$project = json_decode($http->post('/v2/projects',
['headers' => $h, 'json' => ['video_id' => $media['id'], 'dst_lang' => 'es-mx']])->getBody(), true);
while ($project['status'] !== 'merging_done') {
sleep(10);
$project = json_decode($http->get("/v2/projects/{$project['id']}",
['headers' => $h])->getBody(), true);
}_done estados. 0s created
11s transcription_started
87s translation_started
99s voiceover_started
154s merging_started
165s merging_done

es-mx y es-es por igual. El registro del proyecto glossary_version, para que las modificaciones posteriores nunca alteren en silencio el trabajo ya terminado.Sí. La API de traducción de video de Rask toma un archivo o enlace de video y un idioma de destino, luego transcribe la voz, la traduce, genera la voz AI y la mezcla con el audio de fondo original. Obtienes el video traducido, los archivos de subtítulos y el texto traducido sin ningún paso manual intermedio. Agrega una revisión humana antes de publicar cuando la precisión sea fundamental.
El acceso a la API está incluido en los planes de pago. Generas tu ID de cliente y tu clave secreta en la aplicación y puedes empezar a hacer llamadas de inmediato. Los términos empresariales, los precios por volumen y la cobertura de idiomas personalizados se gestionan a través de nuestro equipo.
Credenciales de cliente OAuth 2.0. Intercambia tu ID de cliente y secreto por un token de acceso, luego envíalo como token de portador (bearer token) en cada solicitud. Los tokens son válidos por una hora, así que guárdalos en caché y reutilízalos.
Asíncrono. La creación de un proyecto responde de inmediato y comienza la traducción. Realiza consultas a GET /v2/projects/{id} hasta que el estado sea merging_done. La entrega por webhooks forma parte de la incorporación para empresas (enterprise).
No hay ninguno. La API no limita las solicitudes ni cuenta con una cuota por clave. Tu rendimiento está determinado por la profundidad de la cola de procesamiento, y la prioridad de procesamiento forma parte de los términos empresariales.
Más de 135 idiomas de destino, con variantes regionales cuando es necesario, por lo que dst_lang acepta un código de configuración regional como es-mx o pt-br. El idioma de origen se detecta automáticamente, o puedes configurarlo manualmente. La lista completa de idiomas compatibles está en la documentación de la API. Para idiomas fuera del catálogo, contacta a nuestro equipo para evaluar la viabilidad y las opciones disponibles.
Sí. Cada proyecto tiene un idioma de destino, por lo que puedes crear un proyecto por idioma a partir del mismo archivo y ejecutarlos al mismo tiempo. Al no haber límites de velocidad, la traducción por lotes a diferentes idiomas depende únicamente de cuántos proyectos cree tu sistema.
El tiempo de procesamiento varía según el proyecto. Cada proyecto muestra su estado a medida que avanza por la transcripción, traducción, generación de voz y combinación, para que puedas mostrar el progreso a tus usuarios y descargar los archivos cuando la traducción esté lista.
Siete formatos de video (MP4, MOV, MKV, AVI, WebM, M4V, 3GP) y cuatro formatos de audio (MP3, WAV, FLAC, M4A). También puedes subir videos desde YouTube, Google Drive, S3, Vimeo o mediante una URL directa.
Sí. Puedes descargar los subtítulos traducidos en formatos .srt y .vtt junto con el video traducido, sincronizados con el audio traducido. Los subtítulos incrustados en el video se crean directamente en la app de Rask.
Sí. Obtén la transcripción, edita el texto original y deja que Rask lo traduzca de nuevo, o edita el texto traducido directamente para mantener tu propio estilo y tono. Después, vuelve a generar el doblaje del proyecto. Los glosarios mantienen los nombres de marca coherentes en todos los idiomas.
Un modelo de chat general puede traducir una transcripción que le pegues. Para publicar un video traducido, también necesitas transcripción, sincronización de tiempos, voces, mezcla de audio y archivos de subtítulos. La API de traducción de video de Rask genera todos estos elementos directamente desde el archivo de video.
El uso de la API se cobra por minuto de video, redondeando hacia arriba al siguiente minuto completo, utilizando la misma bolsa de minutos de la app de Rask. Los minutos adicionales a tu plan cuestan $3 por minuto, y los precios por volumen se acuerdan con nuestro equipo. La sincronización labial se cobra por separado, con un minuto de vista previa gratis en cada cuenta, y el nuevo doblaje después de una edición solo se cobra por los fragmentos modificados. Comienza con una prueba gratis, sin necesidad de tarjeta.