Referencia de la API

API de entrevistas

Accede por API a tus entrevistas, transcripciones, evaluaciones y vídeos. Cada organización usa su propio token; una clave solo ve los datos de su cuenta. Toda la API es REST sobre HTTPS y devuelve JSON.

Base de la API
curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews

Autenticación

Crea un token (clave egk_…) desde tu panel, en la sección API (necesitas iniciar sesión). El secreto se muestra una sola vez. Mándalo en cada petición en la cabecera Authorization.

Authorization: Bearer egk_TU_TOKEN

Permisos

Cada token lleva los permisos (scopes) que elijas al crearlo. Si a una petición le falta el suyo, la respuesta es 403 missing_scope.

interviews:read
listar y ver entrevistas
interviews:write
crear entrevistas
transcripts:read
leer transcripciones
analysis:read
leer evaluaciones
recordings:read
descargar el vídeo y sus capturas
usage:read
consultar el consumo del periodo
organization:read
leer la ficha de la organización
webhooks:manage
gestionar webhooks y sus entregas

Endpoints

GET/organizations/{org_id}/public/interviews
scope: interviews:read

Lista las entrevistas de la organización (máximo 100, las más recientes primero).

Parámetros

org_id
id de tu organización, en la ruta
curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews
GET/organizations/{org_id}/public/interviews/{interview_id}
scope: interviews:read

Devuelve una entrevista por su id.

Parámetros

interview_id
id de la entrevista, en la ruta

Errores: 404 not_found

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews/{interview_id}
POST/organizations/{org_id}/public/interviews
scope: interviews:write

Crea una entrevista en estado draft. Todos los campos son opcionales.

Cuerpo de la petición

JSON con cualquiera de estos campos: agent_id, candidate_name, candidate_email, job_title, language, scheduled_for (ISO-8601), max_duration_seconds y questions (lista). Con agent_id la entrevista hereda el guion, la voz y la rúbrica del agente (snapshot inmutable) y sus preguntas se añaden antes que las manuales; el puesto, el idioma y la duración se heredan si no los envías.

Errores: 404 agent_not_found

curl -X POST https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews \  -H "Authorization: Bearer egk_TU_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "agent_id": "7c1d…",    "candidate_name": "María López",    "candidate_email": "maria@example.com",    "job_title": "Cuidadora",    "language": "es",    "scheduled_for": "2026-07-20T10:00:00Z",    "max_duration_seconds": 1800,    "questions": ["¿Experiencia con movilidad reducida?"]  }'
GET/organizations/{org_id}/public/interviews/{interview_id}/transcript
scope: transcripts:read

Transcripción de la entrevista. El parámetro format elige el formato.

Parámetros

format
json (defecto) · txt · csv

Errores: 404 no_transcript · 422 invalid_format

curl -H "Authorization: Bearer egk_TU_TOKEN" \  "https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews/{interview_id}/transcript?format=json"
GET/organizations/{org_id}/public/interviews/{interview_id}/analyses
scope: analysis:read

Evaluaciones (versionadas) de la entrevista, con las puntuaciones por competencia. La vigente lleva current: true. Si hubo capturas del vídeo, incluye además emotional (nerviosismo, ansiedad, positividad y confianza sobre 10) y body_language: eso lo estima un análisis de VISIÓN sobre las imágenes, nunca se infiere del texto.

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews/{interview_id}/analyses
GET/organizations/{org_id}/public/interviews/{interview_id}/recording
scope: recordings:read

Descarga el vídeo (MP4). Por defecto responde 302 a una URL firmada de corta vida (usa curl -L); con ?format=url devuelve el enlace en JSON.

Parámetros

format
redirect (defecto, 302) · url (JSON)

Errores: 404 no_recording · 409 recording_not_in_storage (el vídeo aún se está procesando)

# Descarga directa (sigue el redirect 302):curl -L -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews/{interview_id}/recording \  -o entrevista.mp4
GET/organizations/{org_id}/public/interviews/{interview_id}/captures
scope: recordings:read

Fotogramas que se extraen del vídeo al procesarlo, como URLs firmadas de corta vida y en orden (el primero es el avatar del candidato). Si la entrevista no se grabó o aún no se ha procesado, items llega vacío.

Errores: 404 not_found

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/interviews/{interview_id}/captures
GET/organizations/{org_id}/public/usage
scope: usage:read

Saldo del periodo en curso, en segundos. Útil para saber cuánto queda antes de lanzar más entrevistas.

Errores: 404 not_found (no hay periodo activo)

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/usage
GET/organizations/{org_id}/public/organization
scope: organization:read

Ficha de la organización dueña del token. No incluye datos de facturación.

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/organization
GET/organizations/{org_id}/public/webhook-endpoints
scope: webhooks:manage

Endpoints de webhook dados de alta en tu organización.

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/webhook-endpoints
POST/organizations/{org_id}/public/webhook-endpoints
scope: webhooks:manage

Da de alta un endpoint. El secreto de firma se devuelve UNA sola vez: guárdalo para verificar las entregas. La URL debe ser HTTPS y pública (se rechazan loopback, redes privadas y metadata).

Cuerpo de la petición

JSON con url (obligatoria), subscribed_events (lista de eventos; por defecto interview.completed) y enabled.

Errores: 400 unsafe_url · 400 invalid_event_types

curl -X POST https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/webhook-endpoints \  -H "Authorization: Bearer egk_TU_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "url": "https://tu-servidor.example.com/hooks/clara",    "subscribed_events": ["interview.completed", "analysis.completed"]  }'
DELETE/organizations/{org_id}/public/webhook-endpoints/{endpoint_id}
scope: webhooks:manage

Elimina el endpoint. Responde 204 sin cuerpo.

Parámetros

endpoint_id
id del endpoint, en la ruta

Errores: 404 not_found

curl -X DELETE -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/webhook-endpoints/{endpoint_id}
GET/organizations/{org_id}/public/webhook-endpoints/{endpoint_id}/deliveries
scope: webhooks:manage

Historial de las 100 últimas entregas del endpoint, con su intento y su código de respuesta.

Parámetros

endpoint_id
id del endpoint, en la ruta

Errores: 404 not_found

curl -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/webhook-endpoints/{endpoint_id}/deliveries
POST/organizations/{org_id}/public/webhook-deliveries/{delivery_id}/retry
scope: webhooks:manage

Reencola una entrega fallida. Solo vale para las que están en failed; el worker la reintenta en su siguiente pasada.

Parámetros

delivery_id
id de la entrega, en la ruta

Errores: 404 not_found (no existe o no está en failed)

curl -X POST -H "Authorization: Bearer egk_TU_TOKEN" \  https://entrevistas.tribbe.es/api/v1/organizations/{org_id}/public/webhook-deliveries/{delivery_id}/retry

Webhooks

En vez de preguntar por el estado de una entrevista cada pocos segundos, date de alta un endpoint y te avisamos nosotros. Se gestionan con el permiso webhooks:manage, desde esta API o desde tu panel.

Eventos

interview.created
se ha creado una entrevista.
interview.link_opened
el candidato ha abierto su enlace corto (una vez por dispositivo y ventana de 30 min; las previsualizaciones de WhatsApp o Slack no cuentan).
interview.started
el candidato ha entrado y la conversación ha empezado.
interview.completed
la entrevista ha terminado y se ha cerrado la sesión.
interview.cancelled
la entrevista se ha cancelado antes de hacerse. `cancelled_by` dice quién: «team» si la canceló el equipo desde el panel, o «candidate» si la canceló la propia persona desde el enlace de su correo, y entonces llegan también su `reason` y su `comment`.
interview.failed
la entrevista no ha podido completarse.
transcript.completed
la transcripción está lista.
analysis.completed
la evaluación está lista.
usage.limit_near
queda poco saldo en el periodo.
usage.limit_reached
se ha agotado el saldo del periodo.

Verificar la firma

Cada entrega llega con la cabecera x-webhook-signature en formato t=<timestamp>,v1=<hmac>. El HMAC es SHA-256 sobre {timestamp}.{cuerpo} con el secreto whsec_… que se te mostró al crear el endpoint. Compara siempre en tiempo constante y rechaza los timestamps viejos: así una entrega antigua no se puede reenviar contra ti.

El cuerpo incluye un event_id estable: úsalo para descartar duplicados, porque un reintento repite el mismo evento.

Reintentos

Se considera entregada si respondes 2xx. Si no, se reintenta con espera creciente hasta 6 intentos y la entrega queda en failed; desde ahí puedes reencolarla a mano. Responde rápido y haz el trabajo pesado después: si tardas, cuenta como fallo.

# Pythonimport hashlib, hmac, timedef verificar(secreto: str, cabecera: str, cuerpo: bytes) -> bool:    partes = dict(p.split("=", 1) for p in cabecera.split(","))    t, v1 = partes["t"], partes["v1"]    if abs(time.time() - int(t)) > 300:   # 5 min de tolerancia        return False    esperado = hmac.new(        secreto.encode(), f"{t}.".encode() + cuerpo, hashlib.sha256    ).hexdigest()    return hmac.compare_digest(esperado, v1)

Errores

Los errores se devuelven con el código HTTP correspondiente y un cuerpo application/problem+json con la forma {type, status, code, detail, instance}. El campo code es estable: es el que conviene mirar desde el código, no el texto.

401 missing_api_key · invalid_api_key
falta el token o no es válido / está revocado o caducado.
403 missing_scope
el token no tiene el permiso requerido.
403 wrong_organization
el token es de otra organización.
404 not_found · no_recording · no_transcript · agent_not_found
el recurso no existe, es de otra organización o aún no está listo.
409 recording_not_in_storage
el vídeo existe pero aún se está procesando; reinténtalo.
400 unsafe_url · invalid_event_types
la URL del webhook no es pública/HTTPS, o el evento no existe.
422 invalid_format
formato de transcripción no válido.