Flowmingo emits notifications whenever candidates move through invitation, interview, or evaluation workflows. This section explains how to create webhook endpoints, secure them with HMAC signatures, and understand the payloads you will receive so downstream systems (ATS, HRIS, Slack bots, etc.) stay in sync.
1. Create a webhook endpoint
Log in to your Flowmingo workspace and navigate to Settings -> Webhooks. Click Create Endpoint and provide:
- Name: A label to identify this endpoint later.
- URL: A publicly accessible HTTPS endpoint you control (for example:
https://your-app.com/api/flowmingo-webhook). - Events: Event types this endpoint should receive.
- Description (optional).
On save, Flowmingo returns a webhook secret. Store it securely. You need this value to verify X-Webhook-Signature.
Managing endpoints:
- Update/Delete: Return to Settings -> Webhooks, open an endpoint, and edit or delete it.
- Regenerate Secret: Rotate the signing secret and update your verifier before removing the old secret.
- Send Test: Trigger a test webhook to validate your endpoint without waiting for a real event.
2. Supported events
| Event | Description | Typical trigger |
|---|---|---|
invitation.status.update |
Invitation email lifecycle updates (accepted, delivered, opened, clicked, failed). | Notification service after Flowmingo sends interview invitations. |
interview.status.update |
Candidate starts/completes an interview. | Candidate interview emits state changes. |
interview.evaluation.update |
New CV/interview/holistic evaluation results are stored. | Evaluation processor finishes scoring. |
Subscribing to a parent event (e.g., invitation.status.update) receives all sub-events of that type. You can also subscribe to specific sub-events only (e.g., invitation.status.update.invitation_email_failed).
3. Payload structure
Flowmingo wraps every event in a consistent envelope:
{
"schema_version": "1.0.0",
"event_type": "invitation.status.update",
"event_id": "3a74fa26-4b66-4534-ba76-073548c95239",
"timestamp": "2026-03-04T01:00:00.000Z",
"organization_id": 123,
"data": {
"...event specific fields..."
},
"is_test": true
}
is_test is only included for test deliveries.
Invitation status payload
Event name: invitation.status.update
{
"interview_set_id": "019bcb66-2d6e-795a-9770-148355e51c51",
"interview_name": "Sales Assessment",
"candidate_id": "019bcb66-66d9-781e-96cc-e4a2b74c7fce",
"candidate_email": "alex@example.com",
"status": "invitation_email_delivered",
"reason": null,
"timestamp": 1732619345123
}
Possible status values:
invitation_email_accepted- Email Acceptedinvitation_email_delivered- Email Deliveredinvitation_email_opened- Email Openedinvitation_email_clicked- Link Clickedinvitation_email_failed- Email Failed
Interview status payload
Event name: interview.status.update
{
"interview_set_id": "019bcb66-2d6e-795a-9770-148355e51c51",
"interview_name": "Sales Assessment",
"candidate_id": "019bcb66-66d9-781e-96cc-e4a2b74c7fce",
"candidate_email": "alex@example.com",
"status": "started",
"timestamp": 1732619445123
}
Possible status values:
started- Interview Startedcompleted- Interview Completed
Interview evaluation payload
Event name: interview.evaluation.update
{
"interview_set_id": "string",
"interview_name": "string",
"candidate_id": "string",
"candidate_email": "string",
"evaluation_type": "cv" | "interview" | "holistic",
"evaluation_score": "number",
"submission_url": "string",
"timestamp": "number"
}
Possible evaluation_type values:
cv- CV Evaluationinterview- Interview Evaluationholistic- CV + Interview Evaluation
Note:
overall_scoreis a decimal value out of 10 (e.g., 8.7 = 87%). Theevaluation_resultobject may include additional fields in the future; rely only on keys your integration needs.
Retries
If your endpoint returns non-2xx or fails, Flowmingo retries with at least ~5 minutes between attempts.
Current behavior is up to 4 total attempts (initial delivery + up to 3 retries) before the event remains in error state.
4. Signature verification
Every delivery includes an X-Webhook-Signature header:
X-Webhook-Signature: t=1732619345,v1=3f2fdd0af4...
tis the UNIX timestamp (seconds).v1is an HMAC-SHA256 digest oftimestamp + '.' + body.- The secret is the exact
whsec_...string Flowmingo returned (do not strip the prefix; if you prefer to store only the hex portion, reattachwhsec_before use).
Example middleware (Node.js/Express) that validates the signature using the raw request body:
import crypto from 'crypto';
const WEBHOOK_SECRET = process.env.FLOWMINGO_WEBHOOK_SECRET!;
function verifySignature(rawBody: Buffer, header: string | string[] | undefined) {
if (!header || Array.isArray(header)) return false;
const parts = header.split(',');
const timestamp = parts.find((p) => p.startsWith('t='))?.split('=')[1];
const signature = parts.find((p) => p.startsWith('v1='))?.split('=')[1];
if (!timestamp || !signature) return false;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(`${timestamp}.${rawBody.toString('utf8')}`)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex'));
}
Reject requests if signature verification fails or if the timestamp is outside your allowed skew window.
Webhook Issues
Signature verification failures: Ensure you're using the raw request body (not parsed JSON) when computing the HMAC signature. The timestamp must match exactly what's in the header.
Missing events: Check that your endpoint URL is correct, HTTPS, and publicly accessible. Verify the endpoint is active and subscribed to the correct event types.
Retry behavior: Non-2xx responses trigger automatic retries up to 3 times with ~5-minute spacing. Ensure your endpoint responds with a 2xx status code to acknowledge successful receipt.