Per gli sviluppatori

Riferimento API

Tutto il flusso di lavoro dei colloqui con IA, disponibile tramite semplice REST e JSON. Crea colloqui, invita candidati su larga scala, leggi i risultati con punteggio e ricevi webhook nel momento in cui un report è pronto.

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

Per iniziare

L’API è una superficie REST con versione sotto /v1. Le richieste e le risposte sono in JSON. Le risorse sono indirizzate tramite brevi codici numerici, mai id interni, quindi tutto ciò che vedi in una risposta può essere memorizzato in sicurezza nei tuoi sistemi.

Ti serve una sola cosa per iniziare: una chiave API. Creala nell’app in Workspace, poi API Keys. La chiave completa viene mostrata una sola volta alla creazione, quindi copiala subito e conservala come una password.

La tua prima richiesta
curl https://api.airbasehq.com/v1/me \
  -H "Authorization: Bearer $API_KEY"
Risposta 200
{
  "company": { "name": "Acme Inc." },
  "apiKey": {
    "name": "Production automation",
    "permissions": {
      "canManageInterviews": true,
      "canManageApplications": true
    }
  }
}

Autenticazione

Ogni richiesta trasporta la tua chiave API come bearer token. Le chiavi sono limitate al tuo spazio di lavoro, quindi nessun id azienda compare mai in un percorso.

Le chiavi hanno la forma cuee_<keyId>_<secret>. Sul nostro lato viene memorizzato solo un hash del segreto, ed è per questo che la chiave viene mostrata una sola volta quando la crei. Alle chiavi si può assegnare una data di scadenza e possono essere revocate in qualsiasi momento dalla stessa pagina.

Header di autenticazione
Authorization: Bearer cuee_0123456789abcdef0123456789abcdef_<64 hex chars>
Content-Type: application/json
  • Una chiave mancante o malformata restituisce 401 authentication_required. Una chiave revocata o scaduta restituisce 401 con invalid_api_key o api_key_expired.
  • Una chiave valida che non dispone di un’autorizzazione richiesta restituisce 403 insufficient_permissions.

Autorizzazioni

Quando crei una chiave scegli cosa può fare. Concedi solo ciò di cui la tua integrazione ha bisogno. Questi tre ambiti coprono oggi l’intera superficie pubblica:

AmbitoEtichetta nell’appCosa sblocca
canManageInterviewsInterviewsCrea e gestisci colloqui con IA, invita candidati, esamina i risultati dei colloqui.
canManageApplicationsTalent PoolVisualizza e gestisci candidati, richiedenti e i relativi record di candidatura.
canViewApplicationsView ApplicationsLeggi i record di candidatura e dei candidati. Necessario anche per gestire i webhook.
  • Le chiavi create negli spazi di lavoro AI Interviewer includono automaticamente questo pacchetto, senza dover selezionare nulla.
  • Gli endpoint elencano di seguito gli ambiti richiesti. Quando sono elencati due ambiti, la chiave necessita di entrambi.

Limiti di frequenza

Ogni chiave API può effettuare 200 richieste ogni 60 secondi sull’intera superficie /v1. Ogni risposta include gli header X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Il superamento del limite restituisce HTTP 429 con un header Retry-After, quindi un client ben educato può semplicemente attendere e riprovare.

Esistono endpoint batch così raramente ti servono molte richieste: una singola chiamata di invito accetta fino a 500 candidati.

Errori

Gli errori usano ovunque un unico involucro stabile. Il campo code è una costante leggibile dalla macchina che non verrà mai rinominata, quindi ramifica su di esso anziché sul messaggio.

Involucro dell’errore
{
  "error": {
    "code": "ai_interview_not_published",
    "message": "Publish the interview before inviting candidates."
  }
}
HTTPCodiciSignificato
400invalid_request, validation_failedIl corpo o la query della richiesta non ha superato la validazione.
401authentication_required, invalid_api_key, api_key_expiredLa chiave è mancante, malformata, revocata o scaduta.
403insufficient_permissions, ai_interview_not_publishedAlla chiave manca un ambito, oppure il colloquio non può ancora accettare candidati.
404not_found, ai_interview_not_found, candidate_not_foundLa risorsa non esiste nel tuo spazio di lavoro.
429frequenza limitataTroppe richieste. Rispetta l’header Retry-After.
500operation_failedQualcosa è andato storto dal nostro lato. Si può riprovare in sicurezza con backoff.

Workspace

Identifica lo spazio di lavoro dietro una chiave e ispeziona cosa può fare la chiave. Utile come test di connessione.

Chi sono

GET/v1/me

Restituisce il nome dell’azienda e le autorizzazioni della chiave chiamante. Funziona con qualsiasi chiave valida, nessun ambito richiesto. Le piattaforme di integrazione la usano per etichettare l’account collegato.

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

Colloqui con IA

Un colloquio con IA è uno screening riutilizzabile: un titolo, un contesto del ruolo facoltativo e delle domande. Pubblicalo, poi invita un numero qualsiasi di candidati. Ogni candidato riceve un link personale e l’IA conduce, registra e valuta la conversazione.

Crea un colloquio con IA

POST/v1/ai-interviewsInterviews

Crea un colloquio con IA autonomo, per esempio uno per ogni ruolo nel tuo ATS. Lascia le domande vuote per configurarle in seguito nell’app, oppure passane fino a 50.

Corpo

titlestringObbligatorioda 1 a 255 caratteri

Nome del colloquio, di solito il ruolo per cui effettua la selezione.

contentstringFacoltativofino a 10,000 caratteri

Contesto del ruolo che l’intervistatore IA usa per guidare la conversazione.

questionsstring[]Facoltativofino a 50 elementi

Le domande da porre. Ciascuna da 1 a 1,000 caratteri.

rubricTemplateCodenumberFacoltativo

Scheda di valutazione con cui assegnare i voti. Per impostazione predefinita usa la scheda di valutazione del tuo spazio di lavoro.

status"draft" | "published"Facoltativopredefinito draft

Solo i colloqui pubblicati possono ricevere candidati.

Richiesta
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"
  }'
Risposta 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"
  }
}

Elenca i colloqui con IA

GET/v1/ai-interviewsInterviews

Elenco paginabile dei tuoi colloqui con il conteggio dei candidati. Filtra per stato o cerca per titolo.

Query

pageintegerFacoltativopredefinito 1

Numero di pagina.

perPageintegerFacoltativoda 1 a 100, predefinito 20

Risultati per pagina.

statusstringFacoltativo

Uno tra draft, published, paused, archived.

searchstringFacoltativoda 2 a 500 caratteri

Ricerca per titolo.

Richiesta
curl "https://api.airbasehq.com/v1/ai-interviews?status=published&perPage=20" \
  -H "Authorization: Bearer $API_KEY"
Risposta 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 }
}

Ottieni un colloquio con IA

GET/v1/ai-interviews/:codeInterviews

Dettaglio completo di un colloquio, comprese le sue domande, il canale, la durata e la scheda di valutazione con cui viene valutato. I campi non ancora configurati vengono restituiti come null.

Percorso

codeintegerObbligatorio

Il codice del colloquio dalle risposte di creazione o elenco.

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

Invita candidati

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

Invita fino a 500 candidati in una sola chiamata e restituisce un link personale al colloquio per ciascuno. Completamente idempotente: reinvitare qualcuno restituisce il suo link esistente con stato skipped, quindi i nuovi tentativi sono sempre sicuri. Il colloquio deve essere pubblicato.

Corpo

candidatesobject[]Obbligatorioda 1 a 500 elementi

Oggetti candidato, vedi i campi qui sotto.

Oggetto candidato (campi principali)

emailstringFacoltativoemail valida

Obbligatorio se non viene fornito phone.

phonestringFacoltativopreferibilmente E.164

Obbligatorio se non viene fornita email. Obbligatorio per i colloqui telefonici.

firstName / lastNamestringFacoltativo

È richiesto un nome, separato o come fullName.

fullNamestringFacoltativo

Alternativa ai nomi separati. Suddiviso automaticamente.

externalIdstringFacoltativo

Il tuo id per il candidato, restituito nei risultati.

preferredCommunicationChannel"email" | "sms"Facoltativo

Come viene recapitato l’invito.

country, city, locationstringFacoltativo

Indizi sulla posizione.

linkedIn, portfolio, websitestringFacoltativo

Link del profilo.

currentTitle, currentCompanystringFacoltativo

Posizione attuale.

resumeTextstringFacoltativofino a 200,000 caratteri

Testo grezzo del CV. Analizzato e inserito nel profilo del candidato.

source, referralSourcestringFacoltativo

Attribuzione. referralSource prevale se sono impostati entrambi.

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

Dati strutturati del profilo. Passa ciò che hai, tutto è facoltativo.

Richiesta
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"
      }
    ]
  }'
Risposta 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
    }
  ]
}
  • Lo stato della riga è invited, skipped o failed. Skipped significa che il candidato era già stato invitato e viene restituito lo stesso link.
  • I link ai colloqui scadono dopo circa 30 giorni.
  • Se l’impostazione di recapito del colloquio è "Skip, deliver the link yourself", noi non inviamo nulla e sei tu a recapitare interviewUrl attraverso il tuo canale.

Elenca i candidati di un colloquio

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

Elenco paginabile dei candidati con la fase attuale, lo stato di elaborazione e l’ultimo punteggio. L’ordinamento recently_scored restituisce solo i candidati valutati, dal punteggio più recente, il che rende banale il polling dei nuovi risultati.

Query

pageintegerFacoltativopredefinito 1

Numero di pagina.

perPageintegerFacoltativoda 1 a 100, predefinito 50

Risultati per pagina.

sortstringFacoltativonewest | recently_scored

Predefinito newest. Usa recently_scored per il polling dei risultati.

Richiesta
curl "https://api.airbasehq.com/v1/ai-interviews/27/candidates?sort=recently_scored" \
  -H "Authorization: Bearer $API_KEY"
Risposta 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 }
}

Ottieni il risultato di un candidato

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

Il report completo di un candidato: profilo, punteggi per criterio con evidenze, coppie di domanda e risposta, tentativi di colloquio e link alla registrazione e alla trascrizione.

Percorso

codeintegerObbligatorio

Il codice del colloquio.

applicationCodeintegerObbligatorio

Dalle risposte di invito, dagli elenchi di candidati o dai webhook.

Risposta 200 (ridotta)
{
  "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 e transcriptUrl sono link firmati che scadono dopo circa 4 ore. Recuperali e memorizzali tempestivamente se archivi i risultati.
  • Entrambi sono null finché non termina l’elaborazione post colloquio. Attendi il webhook interview.scored per sapere che il report è pronto.

Bacino di talenti

Il tuo bacino di talenti è composto da ogni candidato che il tuo spazio di lavoro abbia mai visto, ricercabile con l’IA. Aggiungi candidati direttamente, senza programmare nulla, e ritrovali in seguito con il linguaggio naturale.

Cerca nel bacino di talenti

GET/v1/candidatesView Applications

Una sola casella di ricerca, due comportamenti. Un’email, un nome o un numero di telefono corrisponde direttamente. Qualsiasi altra cosa esegue una ricerca semantica su CV, esperienza, competenze e valutazioni passate, così "senior React developer in Berlin" funziona e basta.

Query

searchstringFacoltativoda 2 a 500 caratteri

Email, nome, telefono o una query in linguaggio naturale. Ometti per elencare prima i più recenti.

pageintegerFacoltativopredefinito 1

Numero di pagina.

perPageintegerFacoltativoda 1 a 100, predefinito 20

Risultati per pagina.

Richiesta
curl "https://api.airbasehq.com/v1/candidates?search=senior+react+developer+in+berlin" \
  -H "Authorization: Bearer $API_KEY"
Risposta 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 compare solo sui risultati semantici. distance è la distanza coseno, un valore più basso indica maggiore vicinanza.

Aggiungi un candidato

POST/v1/candidatesTalent Pool

Aggiunge un candidato al bacino di talenti e lo rende immediatamente ricercabile. Deduplicato per email e telefono: riaggiungere qualcuno completa i campi mancanti e non sovrascrive mai ciò che esiste, quindi la sincronizzazione da un altro sistema è sicura.

Corpo

…candidate fieldsobjectFacoltativo

Stesso oggetto candidato degli inviti: nome più email o telefono obbligatori, tutto il resto facoltativo.

aboutCandidatestringFacoltativofino a 10,000 caratteri

Note libere salvate nel profilo.

Richiesta
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": "…"
  }'
Risposta 201
{
  "candidate": {
    "candidateCode": 19,
    "status": "created",
    "name": "Grace Hopper",
    "email": "[email protected]",
    "phone": null
  }
}
  • Restituisce 201 con stato created per i nuovi candidati, oppure 200 con stato existing in caso di deduplicazione.

Webhook

I webhook inviano gli eventi al tuo server nel momento in cui accadono, così non devi mai fare polling. Iscrivi un URL https agli eventi che ti interessano e verifica ogni consegna con la sua firma.

L’evento principale è interview.scored: si attiva quando il report è effettivamente pronto, punteggi e riepilogo inclusi, non semplicemente quando la chiamata termina.

EventoSi attiva quando
interview.scoredIl report IA è pronto: punteggio complessivo, riepilogo e criteri sono disponibili.
interview.completedLa sessione del colloquio è terminata. La valutazione potrebbe essere ancora in corso.
interview.startedIl candidato ha iniziato il colloquio.
interview.cancelledIl colloquio è stato annullato.
candidate.appliedUn candidato si è registrato autonomamente tramite un link al colloquio condiviso.
candidate.invitedUn candidato è stato invitato, tramite API o da un recruiter.

Crea un webhook

POST/v1/webhooksView Applications

Iscrive un endpoint https a uno o più eventi. Il segreto di firma viene restituito una sola volta, solo alla creazione. Puoi avere fino a 10 webhook attivi.

Corpo

urlstringObbligatoriosolo https

Il tuo endpoint. Gli indirizzi privati e interni vengono rifiutati.

eventsstring[]Obbligatorioda 1 a 6 elementi

Eventi dal catalogo qui sopra.

Richiesta
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"]
  }'
Risposta 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"
  }
}

Elenca i webhook

GET/v1/webhooksView Applications

Tutte le iscrizioni con lo stato di salute delle consegne: fallimenti consecutivi e l’ultimo successo e fallimento. I segreti non vengono mai restituiti di nuovo.

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

Elimina un webhook

DELETE/v1/webhooks/:webhookIdView Applications

Annulla l’iscrizione dell’endpoint. Le consegne si interrompono immediatamente.

Percorso

webhookIduuidObbligatorio

L’id del webhook dalla creazione o dall’elenco.

Risposta 200
{ "deleted": true }

Ricevere le consegne

Ogni consegna è una POST al tuo URL con il nome dell’evento nell’header X-Cuee-Event e un corpo firmato. Rispondi con un qualsiasi 2xx entro 10 secondi. Qualsiasi altra cosa viene ritentata con backoff esponenziale e, dopo 20 fallimenti consecutivi, l’iscrizione viene disattivata, come puoi vedere nell’elenco dei webhook.

Consegna per 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"
  }
}
Verifica 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 è un HMAC SHA-256 di "<timestamp>.<raw body>" con il tuo segreto whsec. Verifica sempre rispetto al corpo grezzo della richiesta, prima di qualsiasi parsing JSON.
  • I payload contengono solo codici numerici, mai id interni. Usa applicationCode con l’endpoint del risultato del candidato per recuperare il report completo.