UtteraUttera

Autenticación

Cabecera Authorization: Bearer sk-echo-... en todas las peticiones. La clave se muestra una sola vez al crearla: guárdala. Si la pierdes, revócala y crea otra.

No la pongas en el navegador. La clave da acceso a tu bolsa de créditos. Llama a la API desde tu servidor, nunca desde código que el usuario final pueda leer.

Restringir una clave a unas IPs

Cada clave puede limitarse a las direcciones desde las que tiene sentido que se use. Si tu integración vive en un servidor con IP fija, una clave robada deja de servir de nada fuera de él.

Se configura en tu cuenta, en la columna IPs permitidas de cada clave. Se admiten direcciones sueltas y redes:

203.0.113.7, 198.51.100.0/24, 192.0.2.10

En blanco, la clave funciona desde cualquier sitio, que es el comportamiento por defecto.

Una petición desde una IP que no está en la lista recibe 403 con el código ip_not_allowed y, en el cuerpo, la IP que hemos visto — que es justo lo que necesitas para añadirla si te has dejado una:

{
  "error": "ip_not_allowed",
  "message": "This API key is restricted to a list of IP addresses and this request does not come from one of them",
  "client_ip": "203.0.113.55"
}
Es un 403, no un 401. La clave es buena; lo que no vale es el sitio desde el que llama. Distinguirlo importa: un 401 te haría rotar una clave que estaba perfectamente.

La restricción cubre todos los endpoints autenticados, incluido /v1/usage/last. Quien roba una clave no siempre quiere gastarla; a veces le basta con ver cuánto gasta su dueño.

Antes de restringir una clave en producción, comprueba desde qué IP sales de verdad. No siempre es la que crees: detrás de un NAT, de un balanceador o de una salida a internet con varias líneas, tu tráfico puede aparecer desde direcciones distintas. Lanza una petición, mira el client_ip que te devuelve el 403, y añade esa.

Análisis en la misma petición

Una transcripción puede traer análisis de voz sin subir el audio otra vez. Se piden en la cadena de consulta, separados por comas:

curl https://api.uttera.ai/v1/audio/transcriptions?extras=sentiment,profile,diarize \
  -H "Authorization: Bearer $UTTERA_API_KEY" \
  -F file=@grabacion.m4a \
  -F model=whisper-1
ExtraDevuelveEn la respuesta
sentimenttono emocionalsentiment
profileperfil del hablante (edad, género)profile
diarizequién habla y cuándodiarize

Los tres corren en paralelo sobre el mismo audio, así que pedir los tres tarda casi lo mismo que pedir uno. Cada uno se cobra aparte, y solo si se ejecuta: si un análisis falla, la transcripción llega igual y la respuesta trae un array errors diciendo cuál faltó — y ese no se factura.

sentiment necesita plan Developer o superior; profile y diarize, cualquier plan con inteligencia de audio. Un nombre que no sea uno de los tres devuelve 400 con la lista válida, no una transcripción silenciosamente sin análisis.

Para sentiment con nivel por segmentos o dimensional (valencia, activación, dominancia), use el endpoint suelto /v1/audio/sentiment: en extras va siempre el nivel global.

Formatos e idiomas

Audio de entrada: wav, mp3, flac, ogg, opus, aiff, m4a y webm. webm es lo que graba un navegador y m4a lo que graba un móvil, así que ambos sirven tal cual para transcribir.

Para el análisis de voz —tono, perfil del hablante, interlocutores— hacen falta wav, mp3, flac, ogg o opus: webm y m4a se rechazan con 415 antes de gastar nada, y la respuesta dice con qué formatos reintentar.

Audio de salida (response_format de voz): wav, mp3, opus, flac y pcm. pcm es PCM crudo sin cabecera, así que por la webapp no se ofrece —no lo reproduce un navegador— y al usarlo por API hay que decirle al decodificador los cuatro parámetros, porque el fichero no los lleva:

VozFrecuenciaMuestraCanalesOrden
estándar24 000 Hz16 bits con signo1 (mono)little-endian
HD48 000 Hz16 bits con signo1 (mono)little-endian

La frecuencia es la nativa de cada voz y no se remuestrea: la HD genera a 48 kHz y se entrega tal cual. Lo único que cambia entre los dos es la frecuencia; decodificarlo con la que no toca no suena peor, suena al doble o a la mitad de velocidad. Con wav, flac u opus esto no aplica: el fichero lo declara solo.

# voz estándar
ffmpeg -f s16le -ar 24000 -ac 1 -i voz.pcm voz.wav
# voz HD
ffmpeg -f s16le -ar 48000 -ac 1 -i voz.pcm voz.wav

Cualquier otro valor de response_format devuelve 422 con la lista válida.

Tamaño: hasta 150 MB por petición y 2 horas de audio. Un WAV sin comprimir de 2 horas no cabe: para audios largos, envíelo comprimido. El detalle, en tamaños y duración.

Transcripción: detecta el idioma automáticamente y cubre los que soporta Whisper.

Voz: depende del motor, y la diferencia es grande. La voz estándar (tts-1) habla los nueve de la tabla de abajo. La voz de alta calidad (tts-1-hd) habla unos 30 —además de esos nueve, alemán, ruso, polaco, neerlandés, los nórdicos, griego, turco, árabe, coreano y varios del sudeste asiático, entre otros— y no hace falta declarar el idioma: se deduce del texto. Está explicado en Tres voces, no dos.

Traducción: ~50 idiomas de texto. La cadena sintetiza con la voz estándar, así que con voz son estos nueve:

CódigoIdiomaCódigoIdioma
eninglésititaliano
en-gbinglés británicojajaponés
esespañolptportugués
frfrancészhchino
hihindi

Catálogo de voces

Voces estándar disponibles con model: tts-1:

alloy · echo · fable · nova · onyx · shimmer

El catálogo ampliado está en revisión; se publicará cuando esté cerrado.

Créditos

Cada servicio cobra por lo que consume. Estos son los coeficientes vigentes:

ServicioSe cobra porCréditosUna hora de audio
Transcribirsegundo de audio de entrada0,032673117,6
Voz estándarsegundo de audio generado0,02762699,5
Voz clonadasegundo de audio generado0,4222041.519,9
Tonosegundo de audio0,00509018,3
Perfil del hablantesegundo de audio0,00346412,5
Interlocutoressegundo de audio0,02093875,4
Traducciónsegundo de audio de entrada0,080000288,0
Resumen (LLM)token de entrada0,001605
Resumen (LLM)token de salida0,080650
Un token de salida cuesta 54 veces uno de entrada. Generar es mucho más caro que leer, y por eso el tramo del modelo domina la factura de un resumen aunque la transcripción sea larga.

Cómo se compone cada servicio

ServicioFórmula
TranscribirSTT
Transcribir + tonoSTT + tono
VozTTS sobre los segundos generados
TraducirSTT + TTS del audio generado + recargo de traducción
ResumirSTT + perfil + interlocutores + tokens del modelo

Ejemplo real

Una grabación de 40 minutos (2.424 s) traducida al inglés con voz:

transcripción     79,22   2.424,5 s x 0,032673
voz               43,18   2.055,8 s x 0,021004   (el inglés sale ~15 % más corto)
traducción       193,96   2.424,5 s x 0,080000
                 ──────
                 316,36 créditos
Se cobra el audio que se genera, no el que subes. Al traducir, el idioma destino casi nunca dura lo mismo que el origen.

Planes y límites

Plan€/mesCréditosConcurrenciaVoz alta calidadClonadoResumirSLA
Free05001
Startup197.5003
Developer9950.00015
Professional299200.0005095,0 %
Business999800.00015099,0 %
Enterprisea medidaa medidaa medida99,9 %

Los créditos se renuevan en la fecha de tu suscripción, no el día 1. Si cambias de plan a uno menor, conservas los créditos ya pagados hasta que venza el periodo.

Límites por segundo

PlanVozTranscripciónAnálisis
Free11
Startup5205
Developer10040050
Professional2501.000200
Business5002.000500

Cada respuesta lleva X-RateLimit-Remaining-Second y X-Credits-Remaining-Monthly para que no tengas que adivinar.

Tamaños y duración máximos

QuéLímite
Tamaño del fichero que envías250 MB
Duración del audio4 horas
Pronunciar: tamaño de la muestra1 MB — es un alumno leyendo una frase, segundos de audio
Resumir: duración de la grabaciónlas mismas 4 horas — no tiene un límite propio más corto
Texto a voz, voz estándar (tts-1)250.000 caracteres — del orden de cuatro a cinco horas de voz, según lo denso que sea el texto
Texto a voz, voz estándar en streamingsin límite de longitud
Texto a voz, voz de alta calidad y voz clonada (tts-1-hd)2.000 caracteres, unos dos minutos y medio

Grabaciones largas: cómo las resume

Una grabación larga no cabe de una vez en el contexto del modelo. En vez de resumir un trozo, la partimos, resumimos cada pieza y luego fusionamos — y la fusión no es un resumen de resúmenes, que perdería información dos veces: se le pide que ordene y una las piezas, conservando todas las cifras, fechas y nombres.

Así que el resumen no tiene un límite propio más corto: lo que se puede transcribir se puede resumir. Medido de punta a punta sobre una grabación de cuatro horas con tono, perfil y diarización: seis minutos, entero, con el principio y el final presentes.

Si alguna vez un resumen volviera cortado, la respuesta lo dice en truncated. No es algo que debas ver, y preferimos decírtelo a darte un resumen recortado que se lee como uno entero.

Dos horas tienen que caber en 150 MB

Los dos límites son independientes y hay que cumplir los dos. Para dos horas completas, eso significa no pasar de 175 kbps:

FormatoLo que cabe en 150 MB
mp3 a 64 kbps5 h 27 min
mp3 a 128 kbps2 h 44 min
mp3 a 160 kbps2 h 11 min
mp3 a 256 kbps1 h 22 min
wav 16 bits, mono, 16 kHz1 h 22 min
wav 16 bits, estéreo, 44,1 kHz14 min

Para voz, un mp3 de 64 kbps no pierde nada que nos importe y te deja sitio de sobra. Si envías wav sin comprimir, cuenta con que dos horas no caben.

Texto a voz: el límite depende de la voz

No hay un límite único, porque las dos voces las genera maquinaria distinta:

Voz estándar (tts-1). Se puede pedir de dos formas:

Para una locución larga, el streaming sigue siendo mejor camino. Empiezas a oír el resultado en segundos en vez de esperar al final, y no hay que meter nada entero en una sola respuesta.

Voz de alta calidad y voz clonada (tts-1-hd). El tope es 2.000 caracteres por petición, unos dos minutos y medio de voz. Es bastante menos, y es una limitación del modelo que da esa voz, no una decisión comercial. Para esta voz el streaming no sirve para textos largos: úsala en fragmentos de un par de miles de caracteres y encadénalos.

Si mandas más, se corta. Por encima de su tope, la voz de alta calidad devuelve audio correcto pero incompleto, sin avisar. Estamos poniendo una comprobación que lo rechace con un error en lugar de recortarlo; hasta entonces, trocea tú el texto y comprueba la duración de lo que recibes.
Los minutos son una equivalencia; el límite se cuenta en caracteres. La velocidad de lectura depende del texto: una prosa con palabras largas avanza más deprisa, en caracteres por segundo, que un diálogo de frases cortas. Entre un caso y otro hay más de un 20 % de diferencia, así que la duración exacta no se puede saber de antemano.

Errores

CódigoQué significaQué hacer
400El fichero no se puede decodificar, o un parámetro no vale.El motivo viene en detail.
401Clave ausente, mal formada o revocada.Revisa la cabecera Authorization.
402Bolsa de créditos agotada.Espera a la renovación o sube de plan.
403Tu plan no incluye ese servicio.El mensaje dice qué plan lo incluye.
413Fichero demasiado grande.Trocea o comprime el audio.
422Petición válida pero imposible de servir.Por ejemplo, audio en un idioma sin voz. No se cobra.
429Demasiadas peticiones por segundo.Respeta Retry-After.
502 503Fallo temporal de un nodo.Se reintenta solo una vez. Reintenta tú pasados unos segundos.
Si una etapa falla, no se cobra. En las cadenas de varios pasos —traducir, resumir— un fallo intermedio devuelve el error sin cargar créditos, y un fallo parcial devuelve lo que sí se pudo hacer con un aviso, cobrando solo esa parte.

Consultar el consumo

El cargo se calcula después de enviarte la respuesta, así que no viene dentro de ella. Para saber lo que te ha costado exactamente una petición:

GET /v1/usage/last
GET /v1/usage/last?endpoint=/v1/summarize

Devuelve los créditos cobrados y el desglose por tramo:

{
  "endpoint": "/v1/summarize",
  "credits": 108.978,
  "breakdown": { "stt": 3.1255, "diarize": 2.0029,
                 "profile": 0.1946, "llm": 103.655 },
  "audio_seconds": 95.66,
  "input_tokens": 2776, "output_tokens": 1230
}

Guarda los diez últimos cargos durante una hora. Es para comprobar al momento, no un histórico de facturación.

Cuánto tarda cada cosa

Números medidos, no promesas. Varían con el nodo que atienda y con la carga del momento:

OperaciónTiempo típico
Transcribir 100 minutos de audio10 a 35 s
Transcribir una grabación de 40 minutosmenos de 30 s
Voz estándar, una frasedécimas de segundo
Voz clonadaBastante más: la muestra hay que procesarla
Acierto de cachémilisegundos
Resumen de una grabación largaEl más lento de sus tramos, no la suma: corren en paralelo

Lo que de verdad hay que configurar bien es el tiempo de espera de tu cliente: el servidor mantiene la conexión hasta 7200 segundos, y el fallo más común al integrar es un cliente con 30 segundos por defecto que corta trabajos que iban perfectamente. Está explicado en Integración.

Versionado y cambios

Lo que integras hoy tiene que seguir funcionando mañana. Este es el compromiso:

Seis meses de preaviso para cualquier cambio que rompa. Si algún día tenemos que cambiar algo de forma incompatible, la versión anterior sigue funcionando al menos seis meses desde que lo anunciamos, y te avisamos por correo a la dirección de tu cuenta.

Para que eso signifique algo, hace falta decir qué cuenta como romper y qué no:

Rompe (seis meses de preaviso)No rompe (puede pasar cualquier día)
Quitar un endpoint o un parámetroAñadir un endpoint nuevo
Quitar o renombrar un campo de la respuestaAñadir un campo a la respuesta
Cambiar el tipo o el significado de un campoAñadir un parámetro opcional
Cambiar el valor por defecto de un parámetroAñadir una voz o un idioma
Hacer obligatorio algo que era opcionalAñadir una cabecera de respuesta
Cambiar un código de error por otro distintoMejorar el texto de un mensaje de error

De ahí sale la regla práctica para tu código: ignora los campos que no conozcas en vez de fallar al encontrarlos. Un cliente que revienta porque la respuesta trae una clave nueva se romperá solo, sin que nadie haya roto nada.

Los precios son caso aparte: no son la interfaz, pero sí tu factura. Una subida de coeficientes se anuncia con treinta días y no se aplica a un ciclo ya pagado. Una bajada se aplica en cuanto está.

Estado del servicio

Si algo va mal, lo primero es saber si es tuyo o nuestro.

GET https://api.uttera.ai/health responde sin necesidad de clave y dice si la API está en pie. Es la comprobación que puedes automatizar.

curl -s https://api.uttera.ai/health

Cada respuesta lleva además una cabecera X-Request-Id. Guárdala cuando algo falle: con ese identificador podemos decirte exactamente qué pasó con tu petición, y sin él la conversación empieza por reconstruir cuál era.

Para cualquier incidencia, escríbenos con el X-Request-Id, la hora aproximada y qué esperabas que pasara.

Y hay una página pública de estado: uttera.ai/estado. Comprueba la API en vivo y lleva el histórico de incidencias, con la duración y la causa de cada una. Se publica toda interrupción que haya afectado a peticiones de clientes, incluidas las cortas: un histórico donde solo salen las caídas grandes no sirve para juzgar a un proveedor.

En estudio

Cosas que nos piden, que tienen sentido y que todavía no están. Las ponemos aquí porque enterarte de que algo no existe después de integrarlo es peor que saberlo ahora:

QuéPara quéEstado
WebhooksQue te avisemos al terminar un trabajo largo, en vez de mantener la conexión abiertaPor decidir
Diccionario de pronunciaciónDecirle al motor cómo se pronuncian nombres propios, marcas y siglasPor decidir
Cuentas de servicio y varios usuariosQue una empresa tenga varias personas y claves separadas bajo una misma cuentaDespués de la beta

Si alguna de ellas te bloquea, dínoslo: lo que nos piden los clientes es lo que decide el orden.