Customer Guide

This guide walks you through setting up and managing webhooks for your Breezy account.

Note

Webhook functionality is available for Pro plans. Please contact [email protected] for details.

Prerequisites

Before you begin, you'll need:

  1. A Breezy Pro account
  2. An API access token (see Authorization)
  3. A publicly accessible HTTPS endpoint to receive webhooks

Getting Your Company ID

Most webhook API calls require your company ID. You can find it by:

  1. Calling the companies endpoint:
curl -X GET https://api.breezy.hr/v3/companies \
  -H "Authorization: {your_api_token}"
  1. The response includes your company ID:
[
    {
        "_id" : "abc123def456",
        "name" : "Your Company Name",
        ...
    }
]

Step 1: Create a Webhook Endpoint

Create an endpoint to start receiving webhooks:

curl -X POST https://api.breezy.hr/v3/company/{company_id}/webhook_endpoints \
  -H "Authorization: {your_api_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/breezy-webhook",
    "description": "Production webhook receiver",
    "events": ["candidateAdded", "candidateStatusUpdated"]
  }'

Response

{
    "id" : "abc123",
    "url" : "https://your-server.com/breezy-webhook",
    "description" : "Production webhook receiver",
    "events" : ["candidateAdded", "candidateStatusUpdated"],
    "status" : "active",
    "enabled" : true,
    "secret" : "whsec_a1b2c3d4e5f6...",
    ...
}

Important

Save the secret value immediately! It is only shown once and cannot be retrieved later.


Step 2: Set Up Your Receiver

Create an endpoint on your server to receive webhooks. Here's a simple Node.js example:

const express = require('express')
const crypto = require('crypto')

const app = express()
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET // The secret from Step 1

app.post('/breezy-webhook', express.json(), (req, res) => {
  // Verify the signature
  const signature = req.headers['x-hook-signature']
  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET)
  hmac.update(JSON.stringify(req.body))
  const calculated = hmac.digest('hex')
  
  if (!crypto.timingSafeEqual(Buffer.from(calculated), Buffer.from(signature))) {
    console.error('Invalid webhook signature')
    return res.status(401).json({ error: 'Invalid signature' })
  }
  
  // Process the webhook
  const { type, object } = req.body
  
  switch (type) {
    case 'candidateAdded':
      console.log('New candidate:', object.candidate.name)
      // Add your logic here
      break
    case 'candidateStatusUpdated':
      console.log('Candidate moved:', object.candidate.name, '->', object.stage.name)
      // Add your logic here
      break
  }
  
  res.status(200).json({ success: true })
})

app.listen(3000)

Step 3: Test Your Setup

Trigger an event in Breezy to test your webhook:

  1. Add a candidate to a position
  2. Check your server logs for the incoming webhook
  3. Verify the signature was validated successfully

Managing Your Endpoints

List All Endpoints

curl -X GET https://api.breezy.hr/v3/company/{company_id}/webhook_endpoints \
  -H "Authorization: {your_api_token}"

View Delivery Stats

The response includes stats for each endpoint:

{
    "stats" : {
        "successful_deliveries" : 42,
        "failed_deliveries" : 1,
        "last_delivery_at" : "2025-01-15T10:30:00Z"
    }
}

Update Events

Add or remove events from an endpoint:

curl -X PUT https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id} \
  -H "Authorization: {your_api_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["candidateAdded", "candidateDeleted", "candidateStatusUpdated"]
  }'

Pause an Endpoint

Temporarily stop webhook delivery:

curl -X POST https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id}/pause \
  -H "Authorization: {your_api_token}"

Resume an Endpoint

Resume webhook delivery:

curl -X POST https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id}/resume \
  -H "Authorization: {your_api_token}"

Delete an Endpoint

curl -X DELETE https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id} \
  -H "Authorization: {your_api_token}"

Quotas

Each customer can create up to 10 webhook endpoints. If you need more, contact [email protected].


Troubleshooting

Not Receiving Webhooks

  1. Check endpoint status - Ensure status is "active" and enabled is true
  2. Check events - Verify you're subscribed to the event type you're expecting
  3. Check your URL - Ensure it's publicly reachable over HTTPS
  4. Check failed_deliveries - If this number is increasing, there may be an issue with your endpoint

Signature Verification Failing

  1. Verify you're using the correct secret (the one returned when creating the endpoint)
  2. Ensure you're computing the signature on the raw JSON body
  3. Use timing-safe comparison functions

Delivery Delays

Webhooks are delivered in near real-time but may be delayed if:

  • Your endpoint is slow to respond (>30 seconds causes timeout and retry)
  • Previous deliveries to your endpoint failed (retries queue up)

Best Practices

  1. Respond quickly - Return a 200 response immediately, process data asynchronously
  2. Verify signatures - Always verify the X-Hook-Signature header
  3. Handle duplicates - Use the _id field to deduplicate in rare cases of redelivery
  4. Monitor stats - Check failed_deliveries regularly to catch issues early
  5. Use descriptive names - Set meaningful descriptions to identify endpoints