Skip to main content

July 20, 2026

New Features

  • Interview Lifecycle Webhooks: Two new webhook events close long-standing gaps in the interview event stream. Previously, retries and cancellations produced no webhook at all — integrators saw repeated interview.started events with no explanation for the gaps between them, and an interview that exhausted its call attempts never emitted a terminal event.
    • interview.rescheduled — Sent when a call attempt does not produce a completed interview and a follow-up attempt has been scheduled. Register with "INTERVIEW_RESCHEDULED".
      • Two-attempt shape: Because this event sits between call attempts, it does not carry a single callAttemptId. Instead it splits previousAttempt (with callAttemptId, mapped status, raw endedReason, durationSeconds, attemptNumber) and nextAttempt (with callAttemptId, scheduledAt, attemptNumber).
      • reason: A stable vocabulary — CANDIDATE_REQUEST, NO_ANSWER, BUSY, VOICEMAIL, TECHNICAL_FAILURE, API_REQUEST, or ADMIN. Branch on this rather than on the raw previousAttempt.endedReason, which is diagnostic only. API_REQUEST means you moved the attempt via PATCH /interviews/{id}/call-attempts/{attemptId}; ADMIN means InstaView staff moved it from the internal admin panel.
      • Moves vs. retries: the PATCH reschedule endpoint moves an existing attempt rather than ending one and creating another, so for reason: "API_REQUEST" (and ADMIN) the same callAttemptId appears on both sides of the payload. Every other reason yields two distinct attempts.
      • candidateRequest: Present only when the candidate asked to be called back. Includes their verbatim rawText and a timeResolved flag — when false, the requested time could not be interpreted and a default slot was used instead, meaning the candidate is not expecting a call at scheduledAt.
      • retryCount / maxAttempts: How close the interview is to exhausting its retry budget. maxAttempts is omitted for candidate-requested reschedules, which do not spend that budget.
    • interview.cancelled — Sent when an interview reaches a terminal state without completing. Register with "INTERVIEW_CANCELLED".
      • reason: MAX_ATTEMPTS_EXCEEDED (every permitted attempt made without reaching the candidate), CANDIDATE_NOT_INTERESTED (declined during the call, with the finer-grained outcome in reasonDetail), USER_REQUEST (cancelled from the InstaView dashboard), or ADMIN (cancelled by InstaView staff from the internal admin panel).
      • No API_REQUEST value: the public API has no interview-level cancel endpoint. DELETE /interviews/{id} removes the interview outright and cancels its pending webhook deliveries, so no interview.cancelled event is emitted for it.
      • Also carries attemptsMade, cancelledBy, and lastCallAttemptId (absent when the interview was cancelled before any call was placed).
    • Event ordering: Every interview now emits exactly one terminal event — interview.completed, interview.cancelled, or interview.failed. See the Webhooks guide for representative sequences.

Behavior Changes

  • Interviews that exhaust their call attempts are now CANCELLED, not FAILED: Reaching the retry ceiling means we stopped trying to reach the candidate, not that the platform malfunctioned, so the interview status now reflects that and stays consistent with the interview.cancelled webhook emitted alongside it. Individual call attempts are still recorded as FAILED. If you filter or report on FAILED interviews, note that this cohort has moved.

Documentation

  • Webhook event types corrected: The webhook resource reference previously documented event types as numeric IDs (events: [3, 0]). The API has always accepted string constants ("INTERVIEW_COMPLETED"); the reference has been corrected throughout.
  • OpenAPI response schema completed: The events enum on webhook responses was missing sourcing.completed, sourcing.failed, enrich.completed, and enrich.failed. Generated clients would have rejected valid responses containing those labels.