Guides

Webhooks

Receive real-time notifications when events happen in your hiring pipeline. Prepzo webhooks are HMAC-signed, support 15+ event types, and include automatic retries.

How It Works

  1. Register a webhook endpoint via the API or dashboard
  2. Select which events you want to receive
  3. Prepzo sends POST requests to your URL when events occur
  4. Verify the signature, process the event, return 200

Create a Webhook

curl -X POST https://prepzo.ai/api/v1/webhooks \
  -H "Authorization: Bearer pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/prepzo",
    "events": ["candidate.created", "application.hired", "interview.scheduled"]
  }'

The response includes a secret field. Store this securely - you'll need it to verify signatures.

Available Events

EventDescription
candidate.createdNew candidate added
candidate.updatedCandidate info changed
candidate.deletedCandidate removed
application.createdNew application submitted
application.updatedApplication details changed
application.stage_changedApplication moved to new stage
application.rejectedApplication rejected
application.hiredCandidate hired
job.createdNew job posted
job.updatedJob details changed
job.closedJob closed
job.archivedJob archived
interview.scheduledInterview scheduled
interview.completedInterview completed
interview.cancelledInterview cancelled
offer.createdOffer sent
offer.acceptedOffer accepted
offer.rejectedOffer declined
note.createdNote added to candidate

Use "*" in the events array to receive all events.

Payload Format

{
  "event": "application.hired",
  "data": {
    "id": "uuid-here",
    "status": "hired",
    "hired_at": "2026-02-19T10:00:00Z",
    "candidate": { "id": "uuid", "full_name": "Jane Smith", "email": "jane@example.com" },
    "job_role": { "id": "uuid", "title": "Senior Engineer" }
  },
  "organization_id": "your-org-uuid",
  "timestamp": "2026-02-19T10:00:01Z"
}

Verifying Signatures

Every webhook includes an X-Prepzo-Signature header containing an HMAC-SHA256 signature of the request body using your webhook secret.

// Node.js verification
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express example
app.post('/webhooks/prepzo', (req, res) => {
  const signature = req.headers['x-prepzo-signature'];
  const event = req.headers['x-prepzo-event'];
  
  if (!verifyWebhook(req.rawBody, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the event
  console.log('Event:', event, req.body);
  res.status(200).send('OK');
});

Testing Webhooks

curl -X POST https://prepzo.ai/api/v1/webhooks/test \
  -H "Authorization: Bearer pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endpoint_id": "your-webhook-endpoint-uuid"}'

This sends a test.ping event to your endpoint and returns the response status and timing.

Retry Policy

If your endpoint returns a non-2xx status or times out (10s), Prepzo increments a failure counter. Endpoints with high failure counts may be automatically disabled.

Best practice: return 200 quickly, then process events asynchronously.