Para desarrolladores

Referencia de la API

Todo el flujo de entrevistas con IA, disponible sobre REST y JSON simples. Crea entrevistas, invita candidatos a escala, lee resultados evaluados y recibe webhooks en el momento en que un informe está listo.

URL basehttps://api.airbasehq.com/v1

Primeros pasos

La API es una superficie REST versionada bajo /v1. Las solicitudes y respuestas son JSON. Los recursos se identifican mediante códigos numéricos cortos, nunca con ids internos, así que todo lo que ves en una respuesta puede guardarse con seguridad en tus propios sistemas.

Solo necesitas una cosa para empezar: una clave de API. Créala en la aplicación en Workspace, luego API Keys. La clave completa se muestra una sola vez al crearla, así que cópiala de inmediato y guárdala como una contraseña.

Tu primera solicitud
curl https://api.airbasehq.com/v1/me \
  -H "Authorization: Bearer $API_KEY"
Respuesta 200
{
  "company": { "name": "Acme Inc." },
  "apiKey": {
    "name": "Production automation",
    "permissions": {
      "canManageInterviews": true,
      "canManageApplications": true
    }
  }
}

Autenticación

Cada solicitud lleva tu clave de API como token bearer. Las claves están limitadas a tu espacio de trabajo, así que ningún id de empresa aparece nunca en una ruta.

Las claves tienen el formato cuee_<keyId>_<secret>. De nuestro lado solo se almacena un hash del secreto, por eso la clave se muestra una sola vez cuando la creas. A las claves se les puede asignar una fecha de caducidad y pueden revocarse en cualquier momento desde la misma página.

Cabecera de autorización
Authorization: Bearer cuee_0123456789abcdef0123456789abcdef_<64 hex chars>
Content-Type: application/json
  • Una clave ausente o mal formada devuelve 401 authentication_required. Una clave revocada o caducada devuelve 401 con invalid_api_key o api_key_expired.
  • Una clave válida que carece de un permiso requerido devuelve 403 insufficient_permissions.

Permisos

Cuando creas una clave eliges lo que puede hacer. Concede solo lo que tu integración necesita. Estos tres ámbitos cubren toda la superficie pública actual:

ÁmbitoEtiqueta en la aplicaciónQué habilita
canManageInterviewsInterviewsCrea y gestiona entrevistas con IA, invita candidatos y revisa los resultados de las entrevistas.
canManageApplicationsTalent PoolConsulta y gestiona candidatos, postulantes y los registros de postulación relacionados.
canViewApplicationsView ApplicationsLee los registros de postulaciones y candidatos. También es necesario para gestionar webhooks.
  • Las claves creadas en espacios de trabajo de AI Interviewer llevan este conjunto automáticamente, sin necesidad de elegir nada.
  • Cada endpoint indica los ámbitos que requiere más abajo. Cuando se listan dos ámbitos, la clave necesita ambos.

Límites de frecuencia

Cada clave de API puede hacer 200 solicitudes por cada 60 segundos en toda la superficie /v1. Cada respuesta incluye las cabeceras X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset. Superar el límite devuelve HTTP 429 con una cabecera Retry-After, así que un cliente que se comporta bien solo tiene que esperar y reintentar.

Existen endpoints por lotes para que rara vez necesites muchas solicitudes: una sola llamada de invitación admite hasta 500 candidatos.

Errores

Los errores usan un mismo envoltorio estable en todas partes. El campo code es una constante legible por máquina que nunca se renombrará, así que ramifica tu lógica según él y no según el mensaje.

Envoltorio de error
{
  "error": {
    "code": "ai_interview_not_published",
    "message": "Publish the interview before inviting candidates."
  }
}
HTTPCódigosSignificado
400invalid_request, validation_failedEl cuerpo o los parámetros de la solicitud no pasaron la validación.
401authentication_required, invalid_api_key, api_key_expiredLa clave falta, está mal formada, revocada o caducada.
403insufficient_permissions, ai_interview_not_publishedLa clave carece de un ámbito, o la entrevista aún no puede aceptar candidatos.
404not_found, ai_interview_not_found, candidate_not_foundEl recurso no existe en tu espacio de trabajo.
429límite de frecuencia superadoDemasiadas solicitudes. Respeta la cabecera Retry-After.
500operation_failedAlgo falló de nuestro lado. Es seguro reintentar con retroceso exponencial.

Espacio de trabajo

Identifica el espacio de trabajo detrás de una clave e inspecciona lo que la clave puede hacer. Útil como prueba de conexión.

¿Quién soy?

GET/v1/me

Devuelve el nombre de la empresa y los permisos de la clave que llama. Funciona con cualquier clave válida, sin requerir ningún ámbito. Las plataformas de integración lo usan para etiquetar la cuenta conectada.

Solicitud
curl https://api.airbasehq.com/v1/me \
  -H "Authorization: Bearer $API_KEY"
Respuesta 200
{
  "company": { "name": "Acme Inc." },
  "apiKey": {
    "name": "Zapier",
    "permissions": {
      "canManageInterviews": true,
      "canManageApplications": true
    }
  }
}

Entrevistas con IA

Una entrevista con IA es un filtro reutilizable: un título, contexto opcional del puesto y preguntas. Publícala y luego invita a cualquier número de candidatos. Cada candidato recibe un enlace personal y la IA conduce, graba y evalúa la conversación.

Crear una entrevista con IA

POST/v1/ai-interviewsInterviews

Crea una entrevista con IA independiente, por ejemplo una por cada puesto en tu ATS. Deja las preguntas vacías para configurarlas después en la aplicación, o pasa hasta 50.

Cuerpo

titlestringObligatorio1 a 255 caracteres

Nombre de la entrevista, normalmente el puesto para el que filtra.

contentstringOpcionalhasta 10 000 caracteres

Contexto del puesto que el entrevistador con IA usa para guiar la conversación.

questionsstring[]Opcionalhasta 50 elementos

Las preguntas a formular. Cada una de 1 a 1 000 caracteres.

rubricTemplateCodenumberOpcional

Tarjeta de evaluación con la que calificar. Por defecto usa la tarjeta de evaluación de tu espacio de trabajo.

status"draft" | "published"Opcionaldraft por defecto

Solo las entrevistas publicadas pueden recibir candidatos.

Solicitud
curl -X POST https://api.airbasehq.com/v1/ai-interviews \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Backend Engineer AI Screen",
    "content": "Screen for Node.js and distributed systems experience.",
    "questions": ["Tell me about a service you built and scaled."],
    "status": "published"
  }'
Respuesta 201
{
  "interview": {
    "code": 27,
    "title": "Backend Engineer AI Screen",
    "content": "Screen for Node.js and distributed systems experience.",
    "status": "published",
    "createdAt": "2026-07-01T09:12:00.000Z",
    "updatedAt": "2026-07-01T09:12:00.000Z"
  }
}

Listar entrevistas con IA

GET/v1/ai-interviewsInterviews

Lista paginada de tus entrevistas con el recuento de candidatos. Filtra por estado o busca por título.

Consulta

pageintegerOpcional1 por defecto

Número de página.

perPageintegerOpcional1 a 100, 20 por defecto

Resultados por página.

statusstringOpcional

Uno de draft, published, paused, archived.

searchstringOpcional2 a 500 caracteres

Búsqueda por título.

Solicitud
curl "https://api.airbasehq.com/v1/ai-interviews?status=published&perPage=20" \
  -H "Authorization: Bearer $API_KEY"
Respuesta 200
{
  "interviews": [
    {
      "code": 27,
      "title": "Backend Engineer AI Screen",
      "status": "published",
      "candidateCount": 42,
      "createdAt": "2026-07-01T09:12:00.000Z",
      "updatedAt": "2026-07-02T14:03:00.000Z"
    }
  ],
  "pagination": { "page": 1, "perPage": 20, "total": 1, "totalPages": 1 }
}

Obtener una entrevista con IA

GET/v1/ai-interviews/:codeInterviews

Detalle completo de una entrevista, incluidas sus preguntas, el canal, la duración y la tarjeta de evaluación con la que califica. Los campos que aún no están configurados se devuelven como null.

Ruta

codeintegerObligatorio

El código de la entrevista de las respuestas de creación o de listado.

Respuesta 200
{
  "interview": {
    "code": 27,
    "title": "Backend Engineer AI Screen",
    "content": "Screen for Node.js and distributed systems experience.",
    "status": "published",
    "questions": ["Tell me about a service you built and scaled."],
    "channel": "audio",
    "duration": 15,
    "scorecard": { "code": 12, "name": "Backend Engineer Scorecard" },
    "createdAt": "2026-07-01T09:12:00.000Z",
    "updatedAt": "2026-07-02T14:03:00.000Z"
  }
}

Invitar candidatos

POST/v1/ai-interviews/:code/invitationsInterviewsTalent Pool

Invita hasta 500 candidatos en una sola llamada y devuelve un enlace de entrevista personal para cada uno. Totalmente idempotente: reinvitar a alguien devuelve su enlace existente con estado skipped, así que los reintentos siempre son seguros. La entrevista debe estar publicada.

Cuerpo

candidatesobject[]Obligatorio1 a 500 elementos

Objetos de candidato, consulta los campos abajo.

Objeto de candidato (campos principales)

emailstringOpcionalcorreo válido

Obligatorio salvo que se indique phone.

phonestringOpcionalE.164 preferido

Obligatorio salvo que se indique email. Obligatorio para entrevistas telefónicas.

firstName / lastNamestringOpcional

Se requiere un nombre, ya sea separado o como fullName.

fullNamestringOpcional

Alternativa a los nombres separados. Se separa automáticamente.

externalIdstringOpcional

Tu propio id para el candidato, que se devuelve en los resultados.

preferredCommunicationChannel"email" | "sms"Opcional

Cómo se entrega la invitación.

country, city, locationstringOpcional

Pistas de ubicación.

linkedIn, portfolio, websitestringOpcional

Enlaces de perfil.

currentTitle, currentCompanystringOpcional

Puesto actual.

resumeTextstringOpcionalhasta 200 000 caracteres

Texto sin formato del currículum. Se procesa para el perfil del candidato.

source, referralSourcestringOpcional

Atribución. referralSource prevalece si se indican ambos.

experiences, educations, skills, certifications, languagesobject[]Opcional

Datos estructurados del perfil. Pasa lo que tengas, todo es opcional.

Solicitud
curl -X POST https://api.airbasehq.com/v1/ai-interviews/27/invitations \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "candidates": [
      {
        "fullName": "Ada Lovelace",
        "email": "[email protected]",
        "phone": "+14155552671",
        "externalId": "ats-4711"
      }
    ]
  }'
Respuesta 200
{
  "summary": {
    "invitedCount": 1,
    "failedCount": 0,
    "skippedCount": 0,
    "phoneDroppedCount": 0
  },
  "candidates": [
    {
      "row": 1,
      "status": "invited",
      "applicationCode": 3,
      "candidateCode": 18,
      "email": "[email protected]",
      "phone": "+14155552671",
      "interviewUrl": "https://interviewer.cuee.ai/<token>",
      "warnings": [],
      "error": null
    }
  ]
}
  • El estado de cada fila es invited, skipped o failed. Skipped significa que el candidato ya había sido invitado y se devuelve el mismo enlace.
  • Los enlaces de entrevista caducan tras unos 30 días.
  • Si la configuración de entrega de la entrevista es "Skip, deliver the link yourself", nosotros no enviamos nada y tú entregas interviewUrl por tu propio canal.

Listar candidatos de una entrevista

GET/v1/ai-interviews/:code/candidatesTalent Pool

Lista paginada de candidatos con la etapa actual, el estado de procesamiento y la última puntuación. El orden recently_scored devuelve solo los candidatos evaluados, con la puntuación más reciente primero, lo que convierte el sondeo de resultados frescos en una sola línea.

Consulta

pageintegerOpcional1 por defecto

Número de página.

perPageintegerOpcional1 a 100, 50 por defecto

Resultados por página.

sortstringOpcionalnewest | recently_scored

newest por defecto. Usa recently_scored para sondear resultados.

Solicitud
curl "https://api.airbasehq.com/v1/ai-interviews/27/candidates?sort=recently_scored" \
  -H "Authorization: Bearer $API_KEY"
Respuesta 200
{
  "candidates": [
    {
      "applicationCode": 3,
      "candidateCode": 18,
      "name": "Ada Lovelace",
      "email": "[email protected]",
      "phone": "+14155552671",
      "currentStage": { "name": "AI Interview", "category": "interview", "orderIndex": 2 },
      "isReady": true,
      "processingStatus": "completed",
      "appliedAt": "2026-07-02T10:00:00.000Z",
      "latestScore": { "overallScore": 82, "scoredAt": "2026-07-02T11:05:00.000Z" },
      "latestInterview": { "interviewStatus": "completed", "channel": "phone" }
    }
  ],
  "pagination": { "page": 1, "perPage": 50, "total": 1, "totalPages": 1 }
}

Obtener el resultado de un candidato

GET/v1/ai-interviews/:code/candidates/:applicationCodeTalent Pool

El informe completo de un candidato: perfil, puntuaciones por criterio con evidencia, pares de pregunta y respuesta, intentos de entrevista y enlaces a la grabación y la transcripción.

Ruta

codeintegerObligatorio

El código de la entrevista.

applicationCodeintegerObligatorio

De las respuestas de invitación, las listas de candidatos o los webhooks.

Respuesta 200 (resumida)
{
  "candidate": {
    "applicationCode": 3,
    "candidateCode": 18,
    "name": "Ada Lovelace",
    "evaluation": {
      "overallScore": 82,
      "summary": "Strong communication and relevant systems experience.",
      "criteria": [
        {
          "criterionName": "Technical depth",
          "score": 85,
          "evidenceCommentary": "Described sharding a Postgres cluster in detail."
        }
      ]
    },
    "interviews": [
      {
        "attemptNumber": 1,
        "interviewStatus": "completed",
        "channel": "phone",
        "cheatStatus": "no_suspicion",
        "recordingUrl": "https://…signed…",
        "transcriptUrl": "https://…signed…"
      }
    ]
  }
}
  • recordingUrl y transcriptUrl son enlaces firmados que caducan tras unas 4 horas. Descárgalos y guárdalos pronto si archivas los resultados.
  • Ambos son null hasta que finaliza el procesamiento posterior a la entrevista. Espera el webhook interview.scored para saber que el informe está listo.

Base de talento

Tu base de talento es cada candidato que tu espacio de trabajo ha visto alguna vez, con búsqueda por IA. Añade candidatos directamente, sin programar nada, y encuéntralos después en lenguaje natural.

Buscar en la base de talento

GET/v1/candidatesView Applications

Un solo cuadro de búsqueda, dos comportamientos. Un correo, un nombre o un número de teléfono coinciden directamente. Cualquier otra cosa ejecuta una búsqueda semántica sobre currículums, experiencia, habilidades y evaluaciones anteriores, así que "desarrollador senior de React en Berlín" simplemente funciona.

Consulta

searchstringOpcional2 a 500 caracteres

Correo, nombre, teléfono o una consulta en lenguaje natural. Omítelo para listar del más reciente al más antiguo.

pageintegerOpcional1 por defecto

Número de página.

perPageintegerOpcional1 a 100, 20 por defecto

Resultados por página.

Solicitud
curl "https://api.airbasehq.com/v1/candidates?search=senior+react+developer+in+berlin" \
  -H "Authorization: Bearer $API_KEY"
Respuesta 200
{
  "candidates": [
    {
      "candidateCode": 18,
      "name": "Ada Lovelace",
      "email": "[email protected]",
      "profileSummary": "Senior engineer, 8 years across fintech and infra.",
      "applicationCount": 2,
      "applications": [
        {
          "applicationCode": 3,
          "jobTitle": "Backend Engineer",
          "stageName": "AI Interview",
          "averageScore": 82
        }
      ],
      "match": {
        "distance": 0.18,
        "type": "semantic",
        "text": "Led a 6 person platform team building React tooling in Berlin."
      }
    }
  ],
  "pagination": { "page": 1, "perPage": 20, "total": 1, "totalPages": 1 }
}
  • match aparece solo en las coincidencias semánticas. distance es la distancia coseno, cuanto menor, más cercana.

Añadir un candidato

POST/v1/candidatesTalent Pool

Añade un candidato a la base de talento y lo hace localizable de inmediato. Se deduplica por correo y teléfono: volver a añadir a alguien completa los campos que faltan y nunca sobrescribe lo que ya existe, así que sincronizar desde otro sistema es seguro.

Cuerpo

…candidate fieldsobjectOpcional

El mismo objeto de candidato que en las invitaciones: nombre más correo o teléfono obligatorios, todo lo demás opcional.

aboutCandidatestringOpcionalhasta 10 000 caracteres

Notas libres almacenadas en el perfil.

Solicitud
curl -X POST https://api.airbasehq.com/v1/candidates \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fullName": "Grace Hopper",
    "email": "[email protected]",
    "currentTitle": "Staff Engineer",
    "resumeText": "…"
  }'
Respuesta 201
{
  "candidate": {
    "candidateCode": 19,
    "status": "created",
    "name": "Grace Hopper",
    "email": "[email protected]",
    "phone": null
  }
}
  • Devuelve 201 con estado created para candidatos nuevos, o 200 con estado existing cuando se deduplica.

Webhooks

Los webhooks envían eventos a tu servidor en el momento en que ocurren, así que nunca tienes que sondear. Suscribe una URL https a los eventos que te importan y verifica cada entrega con su firma.

El evento estrella es interview.scored: se dispara cuando el informe está realmente listo, con puntuaciones y resumen incluidos, no solo cuando termina la llamada.

EventoSe dispara cuando
interview.scoredEl informe de IA está listo: la puntuación global, el resumen y los criterios están disponibles.
interview.completedLa sesión de entrevista terminó. La evaluación puede seguir en curso.
interview.startedEl candidato comenzó la entrevista.
interview.cancelledLa entrevista fue cancelada.
candidate.appliedUn candidato se registró por sí mismo a través de un enlace de entrevista compartido.
candidate.invitedUn candidato fue invitado, por API o por un reclutador.

Crear un webhook

POST/v1/webhooksView Applications

Suscribe un endpoint https a uno o más eventos. El secreto de firma se devuelve una sola vez, únicamente al crearlo. Puedes tener hasta 10 webhooks activos.

Cuerpo

urlstringObligatoriosolo https

Tu endpoint. Las direcciones privadas e internas se rechazan.

eventsstring[]Obligatorio1 a 6 elementos

Eventos del catálogo de arriba.

Solicitud
curl -X POST https://api.airbasehq.com/v1/webhooks \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/airbase",
    "events": ["interview.scored", "candidate.applied"]
  }'
Respuesta 201
{
  "webhook": {
    "id": "3e1f1a3e-1111-2222-3333-444455556666",
    "url": "https://example.com/hooks/airbase",
    "events": ["interview.scored", "candidate.applied"],
    "status": "active",
    "secret": "whsec_<64 hex chars>",
    "createdAt": "2026-07-01T09:12:00.000Z"
  }
}

Listar webhooks

GET/v1/webhooksView Applications

Todas las suscripciones con el estado de entrega: fallos consecutivos y el último éxito y el último fallo. Los secretos nunca se vuelven a devolver.

Respuesta 200
{
  "webhooks": [
    {
      "id": "3e1f1a3e-1111-2222-3333-444455556666",
      "url": "https://example.com/hooks/airbase",
      "events": ["interview.scored"],
      "status": "active",
      "consecutiveFailures": 0,
      "lastSuccessAt": "2026-07-02T11:05:03.000Z",
      "lastFailureAt": null,
      "lastFailureReason": null,
      "createdAt": "2026-07-01T09:12:00.000Z"
    }
  ]
}

Eliminar un webhook

DELETE/v1/webhooks/:webhookIdView Applications

Cancela la suscripción del endpoint. Las entregas se detienen de inmediato.

Ruta

webhookIduuidObligatorio

El id del webhook de la creación o del listado.

Respuesta 200
{ "deleted": true }

Recibir entregas

Cada entrega es un POST a tu URL con el nombre del evento en la cabecera X-Cuee-Event y un cuerpo firmado. Responde con cualquier 2xx en menos de 10 segundos. Cualquier otra respuesta se reintenta con retroceso exponencial, y tras 20 fallos consecutivos la suscripción se desactiva, algo que puedes ver en la lista de webhooks.

Entrega para interview.scored
POST /hooks/airbase HTTP/1.1
Content-Type: application/json
User-Agent: Cuee-Webhooks/1.0
X-Cuee-Event: interview.scored
X-Cuee-Delivery: 8b7f4c2a-9d3e-4f5a-b6c7-d8e9f0a1b2c3
X-Cuee-Signature: t=1751449503,v1=<hex hmac>

{
  "id": "8b7f4c2a-9d3e-4f5a-b6c7-d8e9f0a1b2c3",
  "event": "interview.scored",
  "createdAt": "2026-07-02T11:05:03.000Z",
  "data": {
    "interviewCode": 27,
    "jobTitle": "Backend Engineer AI Screen",
    "applicationCode": 3,
    "candidateCode": 18,
    "name": "Ada Lovelace",
    "email": "[email protected]",
    "phone": "+14155552671",
    "interviewStatus": "completed",
    "channel": "phone",
    "completedAt": "2026-07-02T10:58:41.000Z",
    "cheatStatus": "no_suspicion",
    "overallScore": 82,
    "summary": "Strong communication and relevant systems experience.",
    "summaryBullets": ["8 years backend experience", "Clear system design answers"],
    "scoredAt": "2026-07-02T11:05:00.000Z"
  }
}
Verificar la firma (Node.js)
import { createHmac, timingSafeEqual } from 'node:crypto'

function verify(rawBody, signatureHeader, secret) {
  const { t, v1 } = Object.fromEntries(
    signatureHeader.split(',').map((part) => part.split('='))
  )
  // Reject replays older than 5 minutes
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false

  const expected = createHmac('sha256', secret)
    .update(t + '.' + rawBody)
    .digest('hex')
  return timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
}
  • La firma es un HMAC SHA-256 de "<timestamp>.<raw body>" con tu secreto whsec. Verifica siempre contra el cuerpo sin procesar de la solicitud, antes de cualquier análisis JSON.
  • Las cargas útiles contienen solo códigos numéricos, nunca ids internos. Usa applicationCode con el endpoint de resultado del candidato para obtener el informe completo.