Skip to main content
Webhooks let JobMojito notify your server the moment something happens - rather than you polling the API. When an interview or assessment reaches a milestone, we send an HTTP POST with a JSON payload to a URL you configure. The full payload schema is published as its own OpenAPI document:
https://cool.jobmojito.com/functions/v1/openapi-webhooks

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).
Configure webhooks from the JobMojito admin, or ask your account contact. Because webhooks are environment-scoped, a staging endpoint never receives production events.

Events

Subscribe to one or more of these events:
EventSent when
interview_resultAn 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_collectedThe candidate finishes and their raw answers are collected, before final AI scoring.
interview_failedAn 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 type interview or assessment.
  • interview_result - fires when the result becomes status = active with processing_status = completed and the interview status is completed or completed, 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 until pdf_export_url is populated, then sent.
  • interview_collected - fires while the result is still status = draft and the interview status changes to completed or completed, stopped early (answers collected, not yet finalized/submitted).
  • interview_failed - fires while the result is still status = draft and the interview status changes to failed, abandoned, or terminated, no speech detected.
Because 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:
FieldDescription
idThe interview result id this event is about.
interview_idThe interview definition id.
status / interview_status / processing_statusLifecycle status of the result.
profile_interview_id / profile_idCandidate identifiers.
candidate_name / candidate_email / candidate_phone_number / candidate_external_idCandidate details (when a candidate is linked).
score / ai_analysis_recruiter_scoreScores.
ai_analysis / ai_analysis_recruiter / ai_analysis_recruiter_why_hire / ai_analysis_recruiter_why_not_hireAI analysis.
recruiter_go_next_roundRecruiter decision to advance the candidate.
pdf_export_urlPDF report URL - only when PDF report generation is enabled for the interview.
reasonWhich field(s) changed to trigger this delivery.
{
  "id": "…",
  "interview_id": "…",
  "status": "active",
  "interview_status": "completed",
  "candidate_name": "Jane Doe",
  "candidate_email": "jane@example.com",
  "score": 7.2,
  "ai_analysis_recruiter": "…",
  "recruiter_go_next_round": true,
  "pdf_export_url": "https://…/report.pdf",
  "reason": "score"
}
See the webhooks OpenAPI spec for the complete field list.

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 2xx status 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 by id, 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 or Authorization value that only you know, and reject any request that doesn’t carry it:
POST /your/webhook HTTP/1.1
Authorization: Bearer <the-secret-you-configured>
Content-Type: application/json
Additional good practice:
  • 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.

Replaying / inspecting deliveries

Each delivery attempt is recorded with its request and response. If an endpoint was down, you can review the history and re-trigger a delivery from the admin once it’s back online.