Skip to main content

Completion webhook

When an interview ends, ZenHire's interview backend reports the outcome to the platform via a completion webhook. The platform marks the session terminal and, on a completed session, deducts credits.

This is an internal server-to-server contract. Unlike CV DeepMatch's outbound webhook (which calls your endpoint), the interview completion webhook is called by the interview backend on the platform, not on you. You do not register a URL, you do not receive this call, and you are never given its signing secret. It is documented here so you understand exactly how and when a session reaches completed/failed and when credits are charged.

When it fires

Step ⑧ of the verify-and-fetch lifecycle: the interview backend POSTs to the platform when the live conversation ends. The platform then:

  • marks the session completed (or failed),
  • on completed, deducts credits at the per-minute interview rate (rounded up to the next minute),
  • on failed, charges nothing.

Delivery is idempotent — a duplicate delivery for an already-terminal session is a safe no-op (returns the existing status with charged: 0). This means a retried webhook never double-charges.

Signature

The webhook is HMAC-signed, not session-authenticated. It reuses the same scheme as ZenHire's outbound CV DeepMatch webhooks:

X-Interview-Signature: t=<unix-ts>,v1=<hex hmac-sha256 of "<ts>.<rawBody>">
X-Interview-Signature-Timestamp: <unix-ts>

The HMAC input is "<timestamp>.<raw-request-body>" over the raw bytes, and the timestamp bounds replay (a 5-minute tolerance). The signing secret is held only by the platform and the interview backend.

Payload

{
"status": "completed",
"duration_sec": 742,
"recording_s3_key": "recordings/ses_a1b2c3d4e5f6/audio.wav",
"transcript_s3_key": "transcripts/ses_a1b2c3d4e5f6/transcript.json",
"interview_svc_session_id": "ses_a1b2c3d4e5f6",
"delivery_id": "wh_2026_05_29_001"
}
FieldNotes
statuscompleted or failed.
duration_secRequired on completed. Billed rounded up to the next minute.
recording_s3_key / transcript_s3_keyStorage references, surfaced to you via the Results endpoints.
interview_svc_session_idThe interview backend's own session id.
delivery_idOptional idempotency id (logged).

What you do instead

You don't consume this webhook. To know when a session finishes, poll the session:

curl "https://platform.zenhire.ai/api/v1/interview/sessions/{sessionId}" \
-H "X-API-Key: zh_api_YOUR_KEY"

Watch for status reaching completed (or failed), then fetch results.