Callsistdocs
Guías

Subir audio

Fichero o URL, formatos admitidos y los cinco parámetros que se aceptan y se ignoran.

Hay dos formas de darle audio a Callsist. Con fichero subido la estimación de coste es exacta porque se conoce el tamaño; con URL se asume una duración conservadora.

POST /v1/files

Scope: files:write. Content-Type: multipart/form-data con el campo file.

curl -X POST https://api.callsist.com/v1/files \
  -H "Authorization: Bearer $CALLSIST_API_KEY" \
  -F "file=@llamada.mp3"
{
  "id": "file_9xKp2mQvRt4L",
  "object": "file",
  "filename": "llamada.mp3",
  "bytes": 427617,
  "content_type": "audio/mpeg",
  "created_at": "2026-07-29T08:12:44.812Z"
}
  • Formatos: wav, mp3, flac, mpga, oga, ogg, m4a, mp4.
  • Tamaño máximo: 2 GB. Se rechaza por Content-Length antes de leer el cuerpo.
  • Duración máxima: 10 horas.
  • No hay URLs prefirmadas: el fichero pasa por el dominio de Callsist en streaming.
  • El file_id caduca según la retención por defecto de la organización.

Otros métodos: GET /v1/files/{id} (requiere files:write) y DELETE /v1/files/{id}.

No mandes Idempotency-Key en POST /v1/files. El middleware hashea el cuerpo para detectar reintentos, y para eso lo convierte en una cadena — incluido un multipart de hasta 2 GB. Mándala en POST /v1/transcripts, que es el endpoint que cobra: una subida duplicada solo deja un fichero huérfano, una transcripción duplicada se factura.

POST /v1/transcripts

Scope: transcripts:write. Es asíncrono: devuelve 202 con un id.

Hay que indicar exactamente uno de audio_url o file_id. Mandar los dos, o ninguno, es 400 invalid_audio_source.

{
  "audio_url": "https://…/llamada.mp3",   // máx. 2048 caracteres, http o https
  "file_id": "file_9xKp2mQvRt4L",         // máx. 64 caracteres

  "model": "callsist-scribe-1",           // único valor válido; es el defecto

  "language": "auto",                     // "auto" o ISO-639-1 de dos letras
  "language_hints": ["es", "ca"],         // 1 a 10 códigos. MUY recomendable
  "punctuate": true,
  "format_text": true,
  "custom_vocabulary": ["Fibra Óptica"],  // hasta 1000, 80 caracteres cada uno

  "understanding": { /* los siete módulos */ },

  "priority": "standard",                 // "standard" | "economy"
  "metadata": { "ticket": "T-91823" },
  "retention": "30d"                      // "none" | "24h" | "7d" | "30d"
}

language_hints es lo que más mejora la detección

Pon solo los idiomas que de verdad aparecen en tus llamadas. Quitar al italiano de la competición mejora sensiblemente la discriminación entre castellano y catalán, que es la confusión más frecuente en llamadas peninsulares.

metadata es la pieza que hace útil la integración

Diccionario de hasta 64 caracteres por clave y 512 por valor. Vuelve tal cual en GET /v1/transcripts/{id} y en el listado. Ahí es donde va el id del cliente, el del agente y el del ticket del CRM: es lo que permite cruzar la transcripción con el resto de tus datos sin mantener una tabla de correspondencias aparte.

retention explícito, aunque coincida con tu defecto

No porque haga falta, sino porque deja la intención escrita en la petición y no en una configuración que alguien puede cambiar sin avisar.

Cinco parámetros que se aceptan y no hacen nada

Pasan la validación, no dan error y no cambian el resultado. El pipeline solo recibe language, language_hints, custom_vocabulary, punctuate y format_text.

ParámetroLo que pareceLo que pasa
speaker_labels: falseDesactivar la diarizaciónSe diariza igual
speakers_expected: 2Ayudar al diarizadorSe ignora; el número de hablantes se decide solo
channels: "multichannel"Separar por canalSe ignora; siempre se mezcla a mono
word_timestamps: falseNo devolver wordsVienen igual
language_confidence_thresholdUmbral del detector de idiomaSe ignora

No construyas lógica que dependa de ellos. Para grabaciones de contact center no suele importar —son mono y la diarización acústica funciona—, pero si tienes estéreo con agente y cliente en canales separados, hoy no se aprovecha: se avisa con stereo_source_available en warnings.

Idempotencia

Manda Idempotency-Key: <valor único> en el POST. Durante 24 h:

  • misma clave, mismo cuerpo → se devuelve la respuesta original, con la cabecera Idempotency-Replayed: true, y no se cobra otra vez;
  • misma clave, cuerpo distinto409 idempotency_key_reused.

Úsala siempre. Un reintento de red sin ella crea una segunda transcripción y la cobra. Un buen valor es el file_id, o el id de la llamada en tu sistema.

On this page