POST with a JSON payload to a URL you configure.
The full payload schema is published as its own OpenAPI document:
Configuring a webhook
A webhook is configured per merchant and per environment, with:- URL - your HTTPS endpoint that will receive the
POST. - Events - which events this endpoint is subscribed to (see below).
- Headers - optional custom headers we send with every delivery (use these to authenticate the request - see Securing your endpoint).
Events
Subscribe to one or more of these events:| Event | Sent when |
|---|---|
interview_result | An interview or assessment is submitted by the candidate (the result is finalized and AI-scored). If the interview is configured to generate a PDF report, this is delayed until the report is ready so pdf_export_url is included. Also re-sent when a result field changes afterwards (score, recruiter decision, AI analysis, PDF URL). |
interview_collected | The candidate finishes and their raw answers are collected, before final AI scoring. |
interview_failed | An interview does not complete successfully - failed, abandoned, or terminated with no speech detected. Scoring/AI fields are typically empty for this event. |
Exactly when each event fires
These are the precise conditions the platform evaluates on an interview result (verified against the database triggers). All three only apply to results of typeinterview or assessment.
interview_result- fires when the result becomesstatus = activewithprocessing_status = completedand the interview status iscompletedorcompleted, stopped early(i.e. the candidate submitted it), and one of these fields changed: status, processing status, interview status, score, recruiter AI score, recruiter AI analysis, why-hire / why-not-hire, the recruiter next-round decision, or the PDF report URL. If PDF report generation is enabled, the event is held untilpdf_export_urlis populated, then sent.interview_collected- fires while the result is stillstatus = draftand the interview status changes tocompletedorcompleted, stopped early(answers collected, not yet finalized/submitted).interview_failed- fires while the result is stillstatus = draftand the interview status changes tofailed,abandoned, orterminated, no speech detected.
interview_result re-fires whenever one of the watched fields changes (e.g. a recruiter later marks “go to next round”), you may receive it more than once for the same id - see idempotency.
The payload
Every event delivers the same JSON shape. Key fields:| Field | Description |
|---|---|
id | The interview result id this event is about. |
interview_id | The interview definition id. |
status / interview_status / processing_status | Lifecycle status of the result. |
profile_interview_id / profile_id | Candidate identifiers. |
candidate_name / candidate_email / candidate_phone_number / candidate_external_id | Candidate details (when a candidate is linked). |
score / ai_analysis_recruiter_score | Scores. |
ai_analysis / ai_analysis_recruiter / ai_analysis_recruiter_why_hire / ai_analysis_recruiter_why_not_hire | AI analysis. |
recruiter_go_next_round | Recruiter decision to advance the candidate. |
pdf_export_url | PDF report URL - only when PDF report generation is enabled for the interview. |
reason | Which field(s) changed to trigger this delivery. |
Guaranteed delivery
Webhook delivery is at-least-once and resilient - we don’t drop events if your endpoint is briefly down.- Queued & retried. Every delivery is queued and recorded. If your endpoint doesn’t respond with a
2xx, or doesn’t respond within 60 seconds, the delivery is retried automatically. - Up to 10 attempts. We retry up to 10 times before marking the delivery
gave_up. Every attempt - request and response - is stored in your delivery history so you can see exactly what happened. - Acknowledge fast. Return any
2xxstatus as soon as you’ve safely accepted the event (e.g. written it to a queue/DB). Do slow work afterwards - if your handler is slow, the delivery may time out and be retried.
Design your handler to be idempotent
Because delivery is at-least-once, you may receive the same event more than once (a retry, or a re-send when a field changes). Each event is a snapshot of the current state of the result identified byid, so the safe pattern is to upsert by id and apply the latest payload. Applying the same event twice must be harmless.
Do not assume strict ordering between deliveries - use the payload’s status fields and reason to understand what changed rather than relying on arrival order.
Securing your endpoint
JobMojito sends the custom headers you configured on the webhook with every request (and retry). Use this to authenticate the call - for example, set a secret header orAuthorization value that only you know, and reject any request that doesn’t carry it:
- Serve the endpoint over HTTPS only.
- Verify the secret header before processing the body.
- Be tolerant of new fields - we may add fields to the payload over time.