Skip to main content
Webhooks let your system react to interview lifecycle events in real time — session.completed is the most-listened event, but you can subscribe to anything from session creation through scorecard finalization.

Registering an endpoint

1

Open Developer settings

Settings → Developer → Webhooks inside your workspace.
2

Add an endpoint

Paste your URL. Pick the events you want delivered. Save.
3

Copy the signing secret

A 32-byte secret is generated for your endpoint. Store it in your secret manager — you’ll use it to verify HMAC signatures on every incoming request.
Webhook endpoints are managed in the dashboard under Developer → Webhooks — add the URL, choose the events, and copy the signing secret.

Event types

EventWhen it fires
session.createdA new session row is created (API call or apply-page submission).
session.startedCandidate joined; AI is interviewing.
session.completedConversation ended naturally. Scorecard not necessarily ready yet.
session.scoredScorecard finalized. Listen for this if you want the per-dimension breakdown.
session.failedCandidate disconnected mid-interview or tech failure interrupted.
session.cancelledRecruiter cancelled before the candidate joined.
participant.createdA new participant was added (via apply flow or API).
application.approvedHR approved an application — candidate can be scheduled.
application.rejectedHR declined an application.

Payload shape

Every webhook delivers a JSON body with a consistent envelope:
{
  "id": "evt_a1b2c3d4",
  "event": "session.scored",
  "occurred_at": "2026-06-02T08:21:47Z",
  "data": {
    "session": {
      "id": "e3a1c2d4-...",
      "status": "completed",
      "score": "8.2",
      "passed": true,
      "recommendation": "hire",
      "evaluation_breakdown": [ /* per-dimension */ ],
      "transcript_url": "https://…",
      "recording_url": "https://…",
      "authenticity_signals": { /* … */ },
      "candidate_id": "ba4f2cdd-...",
      "evaluation_template_id": "ce1cd564-...",
      "external_id": "greenhouse-8821"
    }
  }
}
The data shape varies by event — for participant.* events, you get the participant; for application.*, the application.
Idempotency: deduplicate by id. The same logical event may be delivered more than once during retry storms.

Verifying the signature

Every request carries a intervyo-signature header with an HMAC-SHA256 signature of the raw body, signed with your endpoint’s secret:
intervyo-signature: t=1735689600,v1=2c8ee5d1b5…
Verify before trusting the payload — anyone could post to your URL otherwise:
import crypto from "crypto";

function verify(rawBody: string, signatureHeader: string, secret: string) {
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((kv) => kv.split("=") as [string, string]),
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  // Constant-time comparison
  return crypto.timingSafeEqual(
    Buffer.from(parts.v1, "hex"),
    Buffer.from(expected, "hex"),
  );
}
Verify against the raw body — don’t deserialize, re-serialize, and hash. JSON whitespace changes break the signature. In Express, capture the raw body with express.raw({ type: "application/json" }) before parsing.

Retries

If your endpoint returns a non-2xx status (or times out at 10 seconds), the platform retries with exponential backoff:
AttemptDelay
1immediate
230 s
32 min
410 min
51 hour
66 hours
724 hours
After 7 failed attempts the event is dropped and a webhook.delivery_failed metric is incremented on your workspace. Subsequent events are still attempted — failures don’t suspend the endpoint.

Ordering

Events are delivered in order per session. You’re guaranteed to see session.created before session.started, and session.scored after session.completed. Across sessions there’s no global ordering — events for session A can arrive interleaved with events for session B.

Testing your endpoint

The webhook settings page has a Send test event button that fires a session.scored payload with synthetic data. Useful for verifying your endpoint + signature verification before live traffic hits it. You can also re-deliver any past event from the Logs tab on the endpoint detail page — useful when you’ve fixed a bug and want to backfill the events you missed.
Last modified on June 2, 2026