
Base URL: https://api.inwista.ai/v1Crea una clave de API en Dashboard → API Keys (solo administradores del espacio de trabajo). La clave se muestra una sola vez — guárdala como si fuera una contraseña.
Envía la clave como token Bearer en cada petición. Cada clave está vinculada a un único espacio de trabajo: todo lo que devuelve la API le pertenece. Los recursos creados a través de la API son visibles en el dashboard, pero los proyectos del dashboard no se exponen a través de la API.
Todo fallo de autenticación — cabecera ausente, clave desconocida, clave revocada — devuelve la misma respuesta 401.
curl https://api.inwista.ai/v1/transcriptions \
-H "Authorization: Bearer inw_live_4f6a…"Todos los errores comparten el mismo formato: un objeto con un código legible por máquinas y un mensaje legible por personas. Dentro de v1 los códigos solo se añaden, nunca cambian — construye sobre el código, no sobre el mensaje.
{ "error": { "code": "insufficient_credits", "message": "…" } }| Estado | Código | Cuándo |
|---|---|---|
| 401 | invalid_api_key | Fallo de autenticación (por cualquier motivo) |
| 400 | invalid_source_url | No es https, credenciales en la URL, host privado o URL mal formada |
| 400 | conflicting_source | Se enviaron tanto source_url como upload_id; indica exactamente uno |
| 400 | invalid_upload_id | upload_id no es un id de subida válido |
| 400 | upload_not_found | No hay ninguna subida con ese id en este espacio de trabajo |
| 400 | upload_incomplete | Aún no se ha enviado ningún archivo a la subida mediante PUT |
| 409 | upload_already_used | La subida ya se ha convertido en una transcripción |
| 409 | upload_in_progress | Otra petición está enviando esta subida ahora mismo |
| 400 | invalid_filename | Falta o no tiene extensión de archivo multimedia |
| 400 | invalid_content_type | No es un tipo MIME como audio/mp4 |
| 400 | invalid_size | size_bytes no es un entero positivo |
| 413 | file_too_large | El tamaño declarado supera los 4 GB |
| 429 | too_many_pending_uploads | El espacio de trabajo ya tiene 25 subidas pendientes de enviar |
| 400 | invalid_language | Falta o no es un código ISO 639-1 |
| 400 | invalid_temperature | No es un número entre 0 y 1 |
| 400 | invalid_num_speakers | No es un entero entre 1 y 32 |
| 400 | invalid_store_media | No es un booleano |
| 400 | invalid_retention | No es "standard" ni "none", o combinado con store_media true |
| 400 | invalid_metadata | No es un objeto o supera 1 KB |
| 400 | invalid_settings | No es un objeto o supera 2 KB |
| 400 | unreadable_source | No se pudo determinar la duración del archivo multimedia |
| 400 | invalid_cursor | starting_after no es un id conocido |
| 400 | invalid_format | Formato de subtítulos no compatible |
| 402 | insufficient_credits | El monedero no cubre el coste |
| 404 | not_found | Recurso desconocido |
| 404 | translation_not_found | El idioma solicitado no tiene una traducción completada para la versión servida |
| 409 | not_ready | Requiere una transcripción completada |
| 409 | operation_in_progress | Todavía se está procesando una mejora |
| 409 | translation_exists | El idioma ya existe para esta versión |
| 400 | invalid_idempotency_key | Cabecera Idempotency-Key vacía o de más de 255 caracteres |
| 400 | idempotency_key_reused | La Idempotency-Key ya se usó para otra petición |
| 409 | idempotency_conflict | Una petición con esta clave aún se está procesando |
| 429 | rate_limited | Demasiadas peticiones — reintenta tras la cabecera Retry-After |
Cada llamada POST cobra créditos al aceptarse, así que una petición que expira y se reintenta a ciegas crearía un segundo trabajo y un segundo cobro. Envía una cabecera Idempotency-Key (cualquier cadena única de hasta 255 caracteres) y los reintentos serán seguros: la respuesta de la primera petición se guarda durante 24 horas y se devuelve sin cambios en cada reintento con la misma clave.
Reutilizar una clave con una petición distinta devuelve 400 idempotency_key_reused; reintentar mientras la original sigue en curso devuelve 409 idempotency_conflict. Las respuestas de error nunca se guardan — una petición fallida nunca conserva su cobro, así que la clave se libera para un reintento limpio.
curl -X POST https://api.inwista.ai/v1/transcriptions \
-H "Authorization: Bearer inw_live_…" \
-H "Idempotency-Key: order-42-transcribe" \
-H "Content-Type: application/json" \
-d '{ "source_url": "…", "language": "en" }'Cada clave de API puede hacer 300 peticiones de lectura (GET) y 60 de escritura (POST) por minuto. El cupo se rellena de forma continua y puede consumirse de una vez. Por encima del límite, la API responde 429 rate_limited con una cabecera Retry-After en segundos.
Toma las cifras como orientativas: reduce el ritmo ante cualquier 429 y prefiere webhooks antes que sondeos frecuentes.
HTTP/1.1 429 Too Many Requests
Retry-After: 12
{ "error": { "code": "rate_limited", "message": "…" } }Las operaciones se miden en créditos del monedero de prepago de tu espacio de trabajo (recárgalo en Dashboard → Billing). La transcripción cuesta 4 créditos por cada minuto iniciado de contenido multimedia. La mejora y la traducción se tarifican según el tamaño del contenido — las mismas tarifas que cobra el estudio. Recuperar, listar y sondear el estado es gratuito.
El cargo se realiza cuando la petición es aceptada. Si una operación falla, el cargo se reembolsa automáticamente y el recurso indica credits_charged: 0. Un rechazo 402 nunca genera cargo alguno.
Los endpoints de listado aceptan limit (por defecto 25, máximo 100) y starting_after — el último id de la página anterior. Las respuestas envuelven los resultados en un objeto de lista con has_more.
{ "object": "list", "data": [ … ], "has_more": true }Envía el archivo multimedia por URL o desde una subida, sondea hasta que esté completed (o usa webhooks) y después recupera los subtítulos. Los estados son processing, completed y failed. Las marcas de tiempo son segundos unix.
El sondeo y el resultado comparten un único endpoint: GET /v1/transcriptions/{id} es donde consultas el estado Y donde vive el recurso terminado — no hay un endpoint de resultados aparte. La única excepción son los propios archivos de subtítulos, que siempre se sirven desde el endpoint de subtítulos porque son cuerpos de archivo en bruto, no JSON.
/v1/transcriptionsConvierte cualquier archivo multimedia alojado en subtítulos precisos y con marcas de tiempo sin que nadie abra el estudio — alimenta directamente tu CMS, tu archivo o tu canalización de publicación.
Se requiere exactamente uno de los dos: source_url o upload_id.
La duración del archivo se comprueba antes de aceptar la petición; el cargo al monedero y el encolado del trabajo ocurren en un único paso atómico. Devuelve 201 con el recurso de transcripción.
Créditos: 4 créditos por cada minuto iniciado de contenido multimedia, cobrados al aceptar el trabajo. Los trabajos fallidos se reembolsan automáticamente.
Cuerpo
| Campo | Tipo | Descripción |
|---|---|---|
source_url | string | URL https pública del archivo multimedia, o una URL de YouTube/TikTok/Vimeo. Indica este parámetro o upload_id |
upload_id | string | El id de una subida cuyo archivo ya se ha enviado mediante PUT (consulta Subidas). Indica este parámetro o source_url |
languageobligatorio | string | Código ISO 639-1, p. ej. "en" o "nb-NO" |
diarization | boolean | Etiquetas de hablante (por defecto false) |
num_speakers | integer | 1–32, pista para la diarización |
temperature | number | Temperatura de muestreo de Whisper entre 0 y 1; por defecto 0 (determinista) |
store_media | boolean | false = solo transcripción: no se preparan archivos de reproducción (por defecto true) |
retention | string | "none" elimina el medio de origen tras la transcripción — la transcripción se conserva (por defecto "standard") |
metadata | object | Tus propias etiquetas, hasta 1 KB, devueltas literalmente |
curl -X POST https://api.inwista.ai/v1/transcriptions \
-H "Authorization: Bearer inw_live_…" \
-H "Content-Type: application/json" \
-d '{
"source_url": "https://cdn.example.com/interview.mp4",
"language": "en",
"diarization": true
}'Respuesta
{
"id": "aB3dE9f2…",
"object": "transcription",
"status": "processing",
"progress": 50,
"language": "en",
"duration_seconds": 1834,
"diarization": true,
"store_media": true,
"retention": "standard",
"source_url": "https://cdn.example.com/interview.mp4",
"upload_id": null,
"temperature": 0,
"metadata": { "internal_ref": "case-42" },
"credits_charged": 124,
"error": null,
"created": 1754558000
}/v1/transcriptionsConcilia tu catálogo con los trabajos procesados o construye un panel sobre todo lo que has transcrito.
Transcripciones creadas por API, las más recientes primero. Paginación estándar.
Créditos: Gratis.
Parámetros de consulta
| Campo | Tipo | Descripción |
|---|---|---|
limit | integer | Tamaño de página, por defecto 25, máximo 100 |
starting_after | string | Cursor: el último id de la página anterior |
curl "https://api.inwista.ai/v1/transcriptions?limit=10" \
-H "Authorization: Bearer inw_live_…"/v1/transcriptions/{id}Sondeo de progreso y resultado final en uno: observa cómo el estado pasa a completed y lee después la duración, el idioma y el cargo en la misma respuesta.
Sondea hasta que el estado sea completed (o registra un webhook, más abajo). Leer una transcripción fallida también activa su reembolso automático.
Créditos: Gratis.
curl https://api.inwista.ai/v1/transcriptions/aB3dE9f2… \
-H "Authorization: Bearer inw_live_…"Respuesta
{
"id": "aB3dE9f2…",
"object": "transcription",
"status": "processing",
"progress": 50,
"language": "en",
"duration_seconds": 1834,
"diarization": true,
"store_media": true,
"retention": "standard",
"source_url": "https://cdn.example.com/interview.mp4",
"upload_id": null,
"temperature": 0,
"metadata": { "internal_ref": "case-42" },
"credits_charged": 124,
"error": null,
"created": 1754558000
}/v1/transcriptions/{id}Elimine un trabajo bajo demanda — control total de sus datos en una sola llamada.
Elimina la transcripción de forma permanente junto con todo lo almacenado: archivos multimedia, contenido de la transcripción, revisiones, traducciones y comentarios. Los contadores de facturación agregados se conservan — no contienen contenido.
Solo se pueden eliminar trabajos completados o fallidos; un trabajo aún en proceso devuelve 409, igual que uno con una mejora o traducción en curso. La eliminación es inmediata e irreversible.
Créditos: endpoints.delete-transcription.pricing
curl -X DELETE https://api.inwista.ai/v1/transcriptions/aB3dE9f2… \
-H "Authorization: Bearer inw_live_…"Respuesta
{
"id": "aB3dE9f2…",
"object": "transcription",
"deleted": true
}/v1/transcriptions/{id}/captionsLleva archivos de subtítulos listos para emisión directamente a tu reproductor, tu MAM o tu canalización de entrega — sin exportaciones manuales ni conversiones de formato por tu parte. En una canalización de producción de video, el SRT o VTT terminado cae directamente en tu NLE, tu herramienta de revisión o tu paso de empaquetado en cuanto se transcribe un montaje.
Devuelve el cuerpo del archivo de subtítulos en bruto con el Content-Type correspondiente — sin envolver en JSON. Responde 409 not_ready hasta que la transcripción se completa.
Créditos: Gratis.
Parámetros de consulta
| Campo | Tipo | Descripción |
|---|---|---|
formatobligatorio | string | srt, vtt, json o txt |
diarization | "true" | Antepone las etiquetas de hablante |
language | string | Sirve una traducción completada en lugar del original; 404 translation_not_found si no existe para la versión servida |
revision | string | Obtén una versión concreta (el id de una mejora es su id de revisión); omitido = la más reciente |
curl "https://api.inwista.ai/v1/transcriptions/aB3dE9f2…/captions?format=srt" \
-H "Authorization: Bearer inw_live_…" -o interview.srtEl formato json es un contrato versionado: { version: 1, language, segments: [{ index, start, end, text, speaker? }] } — segundos con precisión de milisegundos, y dentro de una versión los campos solo se añaden, nunca se eliminan.
Las traducciones pertenecen a la versión para la que se crearon — el revision_id del recurso de traducción la identifica, y la versión de una mejora posterior no las hereda. Pasa ese revision_id como revision para obtener la versión traducida.
Subida directa de archivos para contenido multimedia sin URL pública: archivos locales, complementos de escritorio, archivos protegidos por inicio de sesión. Una subida es un hueco de un solo uso. Créala, envía el archivo mediante PUT a la URL firmada que devuelve y después pasa su id como upload_id al crear la transcripción.
Los bytes van directamente al almacenamiento y nunca pasan por el host de la API, así que funcionan archivos de hasta 4 GB y no se cobra nada hasta que se envía la transcripción. Las subidas que nunca se envían se eliminan al cabo de un día.
/v1/uploadsTranscribe un archivo directamente desde una aplicación de escritorio, un complemento de edición o un servidor privado, sin alojarlo antes en ningún sitio público.
Devuelve 201 con el recurso de subida. La URL firmada es válida durante cuatro horas y está vinculada a las cabeceras de upload_headers: envíalas exactamente como se devuelven en el PUT o el almacenamiento rechazará la petición. La cabecera length-range es la que impone el límite de 4 GB.
Se respeta Idempotency-Key, así que una creación reintentada devuelve la misma subida en lugar de generar un segundo hueco.
Créditos: Gratis. Los créditos se cobran cuando la subida se envía como transcripción, a la tarifa de transcripción.
Cuerpo
| Campo | Tipo | Descripción |
|---|---|---|
filenameobligatorio | string | Debe llevar una extensión de archivo multimedia como .m4a, .wav o .mp4; hasta 180 caracteres |
content_type | string | Tipo MIME del archivo, por defecto application/octet-stream. El PUT debe enviar exactamente este Content-Type |
size_bytes | integer | Tamaño declarado en bytes; responde 413 file_too_large por encima de 4 GB |
# 1. Create the upload
curl -X POST https://api.inwista.ai/v1/uploads \
-H "Authorization: Bearer inw_live_…" \
-H "Content-Type: application/json" \
-d '{ "filename": "interview.m4a", "content_type": "audio/mp4" }'
# 2. PUT the file to upload_url with upload_headers
curl -X PUT "<upload_url>" \
-H "Content-Type: audio/mp4" \
-H "x-goog-content-length-range: 0,4294967296" \
-H "x-goog-if-generation-match: 0" \
--data-binary @interview.m4a
# 3. Submit it
curl -X POST https://api.inwista.ai/v1/transcriptions \
-H "Authorization: Bearer inw_live_…" \
-H "Content-Type: application/json" \
-d '{ "upload_id": "7hKq2mZp…", "language": "en" }'Respuesta
{
"id": "7hKq2mZp…",
"object": "upload",
"status": "pending",
"filename": "interview.m4a",
"content_type": "audio/mp4",
"size_bytes": 84213770,
"transcription_id": null,
"created": 1754558000,
"upload_url": "https://storage.googleapis.com/…",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "audio/mp4",
"x-goog-content-length-range": "0,4294967296",
"x-goog-if-generation-match": "0"
},
"upload_url_expires_at": 1754572400
}Con el audio basta para transcribir: exportar solo la pista de audio deja un largometraje por debajo de 100 MB.
Una subida se convierte en exactamente una transcripción. Enviarla de nuevo responde 409 upload_already_used.
/v1/uploads/{id}Comprueba si un archivo ya se ha enviado y en qué transcripción se ha convertido.
El recurso de subida sin los campos de un solo uso. status pasa a consumed y transcription_id se establece cuando la subida se ha enviado.
Créditos: Gratis.
curl https://api.inwista.ai/v1/uploads/7hKq2mZp… \
-H "Authorization: Bearer inw_live_…"Respuesta
{
"id": "7hKq2mZp…",
"object": "upload",
"status": "consumed",
"filename": "interview.m4a",
"content_type": "audio/mp4",
"size_bytes": 84213770,
"transcription_id": "aB3dE9f2…",
"created": 1754558000
}Mejora de subtítulos con IA — longitud de línea, equilibrado y reglas de sincronización — que produce una nueva versión de los subtítulos. Requiere una transcripción completada. Cuando una mejora termina, la recuperación de subtítulos sirve automáticamente la versión mejorada.
/v1/transcriptions/{id}/enhanceSincronización y equilibrado de líneas con calidad de emisión en piloto automático — entrega subtítulos que pasan el control de calidad sin que un editor los toque. Para productoras, esto automatiza el paso de conformado de subtítulos de la canalización de entrega: cada episodio sale con subtítulos consistentes y conformes a la especificación.
Devuelve 202 con el recurso de mejora.
Créditos: Se calcula a partir del tamaño del contenido de los subtítulos, a la misma tarifa que cobra el estudio, y se descuenta al aceptar el trabajo. Se reembolsa automáticamente en caso de fallo.
Cuerpo
| Campo | Tipo | Descripción |
|---|---|---|
settings | object | Ajustes de mejora del estudio, hasta 2 KB; omítelo para usar los valores por defecto |
Ajustes de la mejora
| Campo | Tipo | Descripción |
|---|---|---|
maxLinesPerBlock | "1" | "2" | Líneas mostradas a la vez; el estándar de emisión y el valor por defecto es 2 |
maxCharactersPerLine | 1–100 | Caracteres por línea; el estándar de emisión y el valor por defecto es 42 |
blockLineBalancing | bottom_heavy | top_heavy | equal | unconstrained | Forma visual de los bloques de dos líneas; por defecto unconstrained |
textCondensation | none | smart | aggressive | Permite a la IA condensar diálogos que se leen demasiado rápido; por defecto none (literal) |
speakerDialogueFormat | none | hyphens | speaker_name | brackets | Cómo se separan varios hablantes en un mismo bloque; por defecto none |
continuationMarkers | none | end | start | both | Colocación del marcador cuando una frase abarca varios bloques; por defecto none |
continuationMarkerStyle | dash | ellipsis | Guion o puntos suspensivos para frases divididas; por defecto dash |
gapBetweenBlocks | none | broadcasting | streaming | sdh | Pausa vacía forzada entre bloques consecutivos; por defecto broadcasting (~99 ms) |
minBlockDuration | 0.1–60 s | Tiempo mínimo que un bloque permanece en pantalla, en segundos; por defecto 1.0 |
maxBlockDuration | > min | Tiempo máximo que un bloque permanece en pantalla, en segundos; por defecto 7.0 |
curl -X POST https://api.inwista.ai/v1/transcriptions/aB3dE9f2…/enhance \
-H "Authorization: Bearer inw_live_…" \
-H "Content-Type: application/json" \
-d '{ "settings": { "maxCharactersPerLine": 37, "textCondensation": "smart" } }'Respuesta
{
"id": "rev8Xk3…",
"object": "enhancement",
"transcription_id": "aB3dE9f2…",
"status": "processing",
"progress": 0,
"credits_charged": 12,
"error": null,
"created": 1754559000
}/v1/transcriptions/{id}/enhancements/{enhancementId}Sondeo y resultado en uno: cuando el estado indica completed, el endpoint de subtítulos ya sirve la versión mejorada.
Sondea hasta completed. Leer una mejora fallida activa su reembolso automático.
Créditos: Gratis.
curl https://api.inwista.ai/v1/transcriptions/aB3dE9f2…/enhancements/rev8Xk3… \
-H "Authorization: Bearer inw_live_…"Traducción de subtítulos que hereda la sincronización del original — una traducción por idioma y por versión de subtítulos. Requiere una transcripción completada.
/v1/transcriptions/{id}/translateUna llamada por idioma convierte una pista de subtítulos terminada en una versión localizada con la misma sincronización — multiplica el alcance de cada video que ya tienes.
Devuelve 202. Responde 409 translation_exists si ese idioma ya existe para la versión actual.
Créditos: Se calcula a partir del tamaño del contenido de los subtítulos, a la misma tarifa que cobra el estudio, por idioma de destino, y se descuenta al aceptar. Se reembolsa automáticamente en caso de fallo.
Cuerpo
| Campo | Tipo | Descripción |
|---|---|---|
target_languageobligatorio | string | Código ISO 639-1, p. ej. "es" |
target_label | string | Nombre para mostrar, hasta 60 caracteres |
curl -X POST https://api.inwista.ai/v1/transcriptions/aB3dE9f2…/translate \
-H "Authorization: Bearer inw_live_…" \
-H "Content-Type: application/json" \
-d '{ "target_language": "es" }'Respuesta
{
"id": "es",
"object": "translation",
"transcription_id": "aB3dE9f2…",
"target_language": "es",
"revision_id": "TRkf2nY7…",
"status": "processing",
"progress": 0,
"credits_charged": 6,
"error": null,
"created": 1754559600
}/v1/transcriptions/{id}/translations/{language}Sondeo y resultado en uno: una vez completed, obtén el archivo de subtítulos traducido desde el endpoint de subtítulos con el parámetro language.
Sondea hasta completed y obtén después los subtítulos traducidos desde el endpoint de subtítulos con el parámetro de consulta language.
Créditos: Gratis.
# Poll the translation resource
curl https://api.inwista.ai/v1/transcriptions/aB3dE9f2…/translations/es \
-H "Authorization: Bearer inw_live_…"
# Once completed, fetch the translated subtitle file
curl "https://api.inwista.ai/v1/transcriptions/aB3dE9f2…/captions?format=vtt&language=es" \
-H "Authorization: Bearer inw_live_…" -o interview-es.vttConfigura un webhook en Dashboard → Integrations → Webhook para recibir eventos transcript.completed en lugar de sondear. Los payloads van firmados con HMAC-SHA256 (X-Inwista-Signature: sha256=<hex> sobre el cuerpo bruto) con el secreto de firma que se muestra una sola vez durante la configuración. Las URL de archivo están prefirmadas y caducan a las 24 horas.
{
"event": "transcript.completed",
"id": "evt_9f2c…",
"timestamp": 1754560000,
"workspaceId": "ws_…",
"project": {
"id": "aB3dE9f2…",
"name": "interview.mp4",
"language": "en",
"durationSeconds": 1834
},
"files": [
{
"format": "srt",
"name": "interview.srt",
"mimeType": "application/x-subrip; charset=utf-8",
"url": "https://…",
"expiresAt": 1754646400
}
]
}