Callsistdocs
Referencia

Errores

Los 28 códigos estables de la API, qué hacer con cada uno y cuáles no se emiten nunca.

Toda respuesta de error tiene la misma forma:

{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_parameter",
    "message": "…",
    "param": "understanding.sentiment_analysis.scope",
    "doc_url": "https://docs.callsist.com/referencia/errores#invalid_parameter",
    "request_id": "req_9xKp2mQvRt4L"
  }
}

Programa contra code, nunca contra message. Los códigos son estables para siempre: añadir uno es libre, renombrar o reutilizar uno es un cambio rompedor. Los mensajes cambian sin aviso y están en castellano.

Guarda request_id. Es el mismo que viaja en la cabecera Callsist-Request-Id de toda respuesta y el que aparece en app.callsist.com/logs. Pegarlo ahí es la diferencia entre depurar en un minuto y abrir un ticket.

Qué reintentar

CódigosQué hacer
Reintentables429, 500, 503Espera exponencial con jitter, respetando Retry-After si viene
No reintentables400, 401, 403, 404, 409, 413, 415, 422Reintentar gasta cuota y no cambia el resultado
Caso aparte402Para el lote entero, avisa y recarga. Seguir mandando solo llena los logs

Trece códigos están publicados y no se emiten jamás. Es deliberado: la taxonomía cubre casos que el pipeline todavía no distingue. Los que se sabe que no llegan están marcados abajo con «no se emite». Maneja los errores por familia de type y no des por hecho que verás cada código de esta lista.


400 · invalid_request_error

La petición está mal. No reintentar sin cambiarla.

invalid_parameter

Un campo tiene un valor que no se admite. param dice cuál, con notación de punto para los anidados: understanding.sentiment_analysis.scope.

missing_parameter

Falta un campo obligatorio. El caso más frecuente es subir un fichero sin el campo de formulario file en POST /v1/files: el nombre no es negociable.

invalid_audio_source

Hay que indicar exactamente uno de audio_url o file_id en POST /v1/transcripts. Mandar los dos, o ninguno, cae aquí.

audio_duration_exceeded

Más de 10 horas de audio. Trocéalo antes de enviarlo.

unsupported_language

El código de idioma no está en el catálogo. language admite "auto" o un ISO-639-1 de dos letras.

sentiment_scope_not_permitted

understanding.sentiment_analysis.scope solo admite "customer". Mandar "agent" cae aquí, y no es un bug pendiente de arreglar: el Reglamento de IA (art. 5.1.f) prohíbe inferir emociones de trabajadores en su entorno laboral, y vincula también al proveedor del sistema.

Esto no impide evaluar la calidad del trabajo de un agente contra una plantilla — eso es evaluación de desempeño sobre hechos observables. Lo que no se puede es preguntar «¿cómo se sentía el agente?».

invalid_model

El identificador de modelo no existe. Consulta GET /v1/models, que es público y sin autenticación. La respuesta no repite el ID que mandaste.

invalid_webhook_url

Solo https en POST /v1/webhooks.

También cae aquí mandar webhook_url, webhook_auth_header o webhook_include_result dentro de POST /v1/transcripts: no existe el webhook por petición. Hasta hace poco se aceptaban en silencio, devolvían 202 y no los leía nadie. Ver Webhooks.


401 · authentication_error

missing_api_key

Falta la cabecera Authorization.

invalid_api_key

La clave no tiene la forma esperada o no existe. Empiezan por sk_live_ seguido de 32 caracteres alfanuméricos; una clave sk_test_ se rechaza por forma, porque el modo de prueba se retiró.

revoked_api_key

La clave se revocó. Ojo con el margen: una clave revocada sigue funcionando hasta 30 segundos, que es lo que dura la caché de autenticación.

expired_api_key

Declarado, no se emite: hoy las claves no caducan solas.


402 · insufficient_credit

insufficient_credit

No hay saldo. POST /v1/transcripts estima el coste y devuelve esto antes de procesar, así que no se gasta nada.

Para el lote y recarga. Reintentar no arregla nada. Configura el aviso de saldo bajo en app.callsist.com/billing: se manda una sola vez al cruzar el umbral hacia abajo, así que un lote de cuatrocientas llamadas por debajo del umbral produce un correo, no cuatrocientos.

spend_cap_reached

Declarado, no se emite todavía.


403 · permission_error

missing_scope

La clave no tiene el permiso que la ruta exige. param dice cuál falta.

También es lo que sale si tu IP está fuera de la lista blanca de la clave, con param: "ip_allowlist". Es el error más desconcertante de la API: si una clave que funcionaba deja de funcionar desde una máquina nueva, mira la lista blanca antes que los scopes.

ip_not_allowed

Declarado, no se emite nunca. El caso que describe sale como missing_scope con param: "ip_allowlist".


404 · not_found_error

resource_not_found

El recurso o el modelo no existen. Vale también para una transcripción de otra organización: no se distingue «no existe» de «no es tuya», a propósito.


409 · conflict_error

idempotency_key_reused

Misma Idempotency-Key, cuerpo distinto, dentro de la ventana de 24 h. Con la misma clave y el mismo cuerpo se devuelve la respuesta original y la cabecera Idempotency-Replayed: true, sin cobrar de nuevo.


413 · payload_too_large

file_too_large

Más de 2 GB. Se rechaza por Content-Length antes de leer el cuerpo.


415 · unsupported_media_type

unsupported_audio_format

Formatos admitidos: wav, mp3, flac, mpga, oga, ogg, m4a, mp4.


422 · unprocessable_audio

Los tres están declarados y ninguno se emite hoy: un audio inservible acaba en una transcripción con status: "failed" o con el aviso asr_no_segments, no en un 422. Están documentados porque el código puede empezar a emitirlos sin ser un cambio rompedor.

audio_corrupt

El fichero no se puede decodificar. No reintentar.

audio_silent

No hay voz en el audio.

audio_too_short

Demasiado corto para transcribir.


429 · rate_limit_error

rate_limit_exceeded

Más de 300 peticiones por minuto y por clave. Espera los segundos de Retry-After.

El cubo es por clave, no por organización: dos claves distintas son dos cubos. Y el sondeo de estado consume del mismo cubo que las llamadas de negocio si van con la misma clave. Ver Lotes y límites.

concurrency_limit_exceeded

Más de 32 transcripciones en vuelo por organización — todo lo que esté en queued o processing. Viene con Retry-After: 30.


500 · api_error

internal_error

Fallo nuestro. Reintentar con espera creciente. No se factura.


503 · service_unavailable

upstream_unavailable

Una dependencia no responde. Reintentar con espera creciente. No se factura.

queue_saturated

Declarado, no se emite. La saturación se manifiesta como espera en la cola, no como error.

On this page