This guide covers webhook management for Breezy integration partners. Partners can create and manage webhook endpoints on behalf of their mutual customers.
Partner vs Customer Webhooks
Partners and customers have separate webhook quotas:
| Owner | Quota | Use Case |
|---|---|---|
| Customer | 10 endpoints | Customer's own integrations |
| Partner | 10 endpoints | Partner's integration with customer |
Partner-created webhooks are isolated from customer-created webhooks. Each has their own quota of 10 endpoints.
Authentication
Partner API calls require two authentication headers:
| Header | Description |
|---|---|
partner-api-key | Your partner API key |
Authorization | Customer's API token (for acting on their behalf) |
Example Request
curl -X GET https://api.breezy.hr/v3/company/{company_id}/webhook_endpoints \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}"For more details on partner authentication, see the Partner API Authorization.
Integration Workflow
1. Customer Authorizes Your Integration
When a customer authorizes your integration, you receive a customer API token that allows you to act on their behalf.
2. Create Webhook Endpoint
Create a webhook endpoint to receive events for this customer:
curl -X POST https://api.breezy.hr/v3/company/{company_id}/webhook_endpoints \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-integration.com/webhooks/breezy/{customer_id}",
"description": "YourIntegration - Customer sync",
"events": ["candidateAdded", "candidateStatusUpdated"]
}'3. Store the Endpoint Details
Save the endpoint ID and secret:
{
"id" : "abc123",
"secret" : "whsec_a1b2c3d4e5f6...",
...
}4. Process Incoming Webhooks
Your webhook receiver should:
- Verify the signature using the stored secret
- Identify the customer from the URL path or payload
- Process the event data
- Return a 200 response
Managing Partner Endpoints
List Your Endpoints
List only the endpoints you created (not the customer's own endpoints):
curl -X GET https://api.breezy.hr/v3/company/{company_id}/webhook_endpoints \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}"Update an Endpoint
curl -X PUT https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id} \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}" \
-H "Content-Type: application/json" \
-d '{
"events": ["candidateAdded", "candidateDeleted", "candidateStatusUpdated"]
}'Delete an Endpoint
When a customer disconnects your integration:
curl -X DELETE https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id} \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}"Common Integration Patterns
Multi-Tenant Webhook Receiver
If you have many customers, use a single webhook URL with customer identification:
https://your-integration.com/webhooks/breezy/{customer_id}
Or include customer identification in the path and parse it server-side.
Per-Customer Webhook URLs
Alternatively, generate unique URLs per customer:
https://your-integration.com/webhooks/breezy/customer_abc123
https://your-integration.com/webhooks/breezy/customer_def456
Secret Management
Store each customer's webhook secret securely:
// Store when creating endpoint
const { id: endpointId, secret } = await createWebhookEndpoint(customerId, ...)
await db.webhookSecrets.upsert({
customerId,
endpointId,
secret: encrypt(secret)
})
// Retrieve when verifying
app.post('/webhooks/breezy/:customerId', async (req, res) => {
const { customerId } = req.params
const { secret } = await db.webhookSecrets.findOne({ customerId })
if (!verifySignature(req.body, req.headers['x-hook-signature'], decrypt(secret))) {
return res.status(401).json({ error: 'Invalid signature' })
}
// Process webhook
})Quotas
Partners have a separate quota of 10 endpoints per partner per customer.
This is independent of the customer's own 10-endpoint quota, so your integration won't use up the customer's webhook slots.
Best Practices
1. Clean Up on Disconnect
When a customer disconnects your integration, delete your webhook endpoints to free up quota:
curl -X DELETE https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id} \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}"2. Use Descriptive Names
Set clear descriptions so customers can identify your endpoints if they view them in the API:
{
"description": "YourCompany - Candidate sync to HR system"
}3. Subscribe to Only Needed Events
Only subscribe to events you actually use. This reduces webhook traffic and processing load.
4. Handle Token Expiration
If a customer's API token expires or is revoked, you'll need to re-authenticate to manage webhooks.
5. Monitor Delivery Stats
Periodically check endpoint stats to detect delivery issues:
curl -X GET https://api.breezy.hr/v3/company/{company_id}/webhook_endpoint/{endpoint_id} \
-H "partner-api-key: {your_partner_api_key}" \
-H "Authorization: {customer_api_token}"Look for increasing failed_deliveries counts.
Support
For partner integration questions, contact [email protected].
