Callsistdocs
Empezar

Primera transcripción

De un mp3 a JSON con hablantes separados, en cuatro llamadas.

Cuatro llamadas: comprobar la clave, subir el audio, encolar la transcripción y recoger el resultado. La transcripción es asíncrona —devuelve un id y el resultado se recoge después—, y esa es la única parte que sorprende a quien viene de una API síncrona.

1. Comprobar la clave

export CALLSIST_API_KEY="sk_live_…"

curl https://api.callsist.com/v1/me \
  -H "Authorization: Bearer $CALLSIST_API_KEY"

Si esto devuelve tu organización y tus scopes, sigue. Si no, ve a Autenticación.

2. Subir el audio

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"
}

También se puede pasar una URL pública en lugar de subir el fichero. Con fichero subido la estimación de coste es exacta porque se conoce el tamaño; con URL se asume una duración conservadora. Los detalles, en Subir audio.

3. Encolar la transcripción

curl -X POST https://api.callsist.com/v1/transcripts \
  -H "Authorization: Bearer $CALLSIST_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: file_9xKp2mQvRt4L" \
  -d '{
    "file_id": "file_9xKp2mQvRt4L",
    "language_hints": ["es", "ca"],
    "understanding": {
      "topic_detection": { "taxonomy": "contact_center" },
      "content_moderation": {},
      "pii_redaction": { "policy": "entity_name" },
      "profanity_filter": { "policy": "mask" },
      "sentiment_analysis": { "scope": "customer" },
      "summarization": { "format": "bullets" },
      "action_items": true
    },
    "retention": "30d",
    "metadata": { "ticket": "T-91823" }
  }'

Responde 202 con el id y una estimación de coste:

{
  "id": "tr_MoKLFufBqnzJ",
  "object": "transcript",
  "status": "queued",
  "estimated_cost": { "eur": 0.0453, "assumed_seconds": 240 }
}

Cuatro decisiones metidas en ese cuerpo, y todas importan:

  • Idempotency-Key es el file_id. Un reintento de red sin clave de idempotencia crea una segunda transcripción y la cobra. Usando el file_id, reintentar devuelve la original con Idempotency-Replayed: true y no cuesta nada.
  • language_hints es lo que más mejora la detección de idioma. Pon solo los que de verdad aparecen en tus llamadas: quitar al italiano de la competición mejora notablemente el castellano contra el catalán.
  • Los siete módulos o ninguno. El pack cuesta 0,29 €/h y solo se aplica con los siete; seis sueltos cuestan 0,35 €/h. Pedir los siete sale más barato que pedir seis.
  • metadata es lo que hace útil la integración. Ahí va el id del ticket, del agente y del cliente; vuelve tal cual al leer la transcripción y te ahorra mantener una tabla de correspondencias aparte.

4. Recoger el resultado

curl https://api.callsist.com/v1/transcripts/tr_MoKLFufBqnzJ \
  -H "Authorization: Bearer $CALLSIST_API_KEY"

Mientras no esté lista, la respuesta es corta: status vale queued o processing. Sondea cada 10 segundos. Cuando pase a completed, llega todo:

{
  "id": "tr_MoKLFufBqnzJ",
  "status": "completed",
  "language": "es",
  "audio_duration": 216.999,
  "billed_duration": 240,
  "text": "Acme Telecom, buenos días, le atiende Marta. ¿En qué puedo ayudarle?…",
  "utterances": [
    { "speaker": "1", "speakerRole": "agent", "text": "…", "start": 0, "end": 5.2 },
    { "speaker": "0", "speakerRole": "customer", "text": "…", "start": 5.66, "end": 15.82 }
  ],
  "speaker_role_confidence": 0.9,
  "understanding": { "…": "…" },
  "pii": { "…": "…" },
  "warnings": [],
  "usage": { "total_eur": 0.041 }
}

Antes de usar nada de ahí, lee warnings. Es la lista de lo que pediste y no llegó. Un módulo que aparece en warnings no está en understanding, y tratarlo como vacío es un error de datos disfrazado de resultado. Y si activaste la redacción de PII, el texto tapado no es text: está en pii.text_redacted. Las dos cosas, en Leer el resultado.

El flujo completo, resumido

 1. GET  /v1/me                    ← comprobar clave y scopes
 2. GET  /v1/balance               ← ¿hay saldo para el lote?
 3. POST /v1/files                 ← subir el mp3          → file_id
 4. POST /v1/transcripts           ← con Idempotency-Key   → tr_…  (202)
 5. GET  /v1/transcripts/{id}      ← sondear cada 10 s hasta completed | failed
 6. leer warnings                  ← ¿llegó lo que pediste?
 7. POST /v1/chat/completions      ← análisis con plantilla, si hace falta

On this page