> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instaview.sk/llms.txt
> Use this file to discover all available pages before exploring further.

# July 2026

> Changelog entries for July 2026

## 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](/guides/webhooks) 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.
