Flowmingo Logo

Integrations

Webhook Integration Guide

Subscribe HTTPS endpoints to Flowmingo events, validate signatures, and stream candidate updates directly into your systems.

Trigger invites programmatically?

Use the API key flow when you need to push candidates into Flowmingo instead of waiting for events.

Open API guideWebhooks retry up to three times automatically—keep your endpoint idempotent and log 2xx acknowledgements.
Webhook Integration

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 Accepted
  • invitation_email_delivered - Email Delivered
  • invitation_email_opened - Email Opened
  • invitation_email_clicked - Link Clicked
  • invitation_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 Started
  • completed - 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 Evaluation
  • interview - Interview Evaluation
  • holistic - CV + Interview Evaluation

Note: overall_score is a decimal value out of 10 (e.g., 8.7 = 87%). The evaluation_result object 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...
  • t is the UNIX timestamp (seconds).
  • v1 is an HMAC-SHA256 digest of timestamp + '.' + body.
  • The secret is the exact whsec_... string Flowmingo returned (do not strip the prefix; if you prefer to store only the hex portion, reattach whsec_ 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.