Webhooks API
Webhooks allow you to receive real-time notifications when events occur in EquipDash, enabling automated workflows and integrations.
What is a Webhook?โ
A webhook is an HTTP callback that sends data to your server when something happens:
- An event occurs in EquipDash (e.g., new booking created)
- EquipDash sends an HTTP POST request to your URL
- Your server receives the event data and takes action
EquipDash Your Server
โ โ
โ Event: booking.created โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโบ โ
โ POST /your-webhook-url โ
โ { event, data, timestamp } โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ 200 OK โ
โ โ
Webhook Structureโ
Webhook
โโโ name (identifier)
โโโ url (your endpoint)
โโโ events[] (subscribed events)
โโโ secret (for signature verification)
โโโ is_active
โโโ failure_count
โโโ last_triggered_at
Available Eventsโ
Booking Eventsโ
| Event | Triggered When |
|---|---|
booking.created | New booking is created |
booking.updated | Booking details change |
booking.cancelled | Booking is cancelled |
booking.completed | Booking marked complete |
booking.picked_up | Rental items are picked up |
booking.returned | Rental items are returned |
booking.checked_in | Customer checks in for an experience |
booking.no_show | Staff mark the booking as a no-show |
booking.status_changed | Booking status changes |
Payment Eventsโ
| Event | Triggered When |
|---|---|
payment.received | Payment is processed |
payment.refunded | Payment is refunded |
payment.balance_due | A balance reminder is sent |
Customer Eventsโ
| Event | Triggered When |
|---|---|
customer.created | New customer added |
customer.updated | Customer details change |
customer.deleted | Customer is deleted |
Product Eventsโ
| Event | Triggered When |
|---|---|
product.created | New product added |
product.updated | Product details change |
product.archived | Product is archived |
Experience Eventsโ
| Event | Triggered When |
|---|---|
experience.created | New experience added |
experience.updated | Experience details change |
experience.archived | Experience is archived |
Other Eventsโ
| Event | Triggered When |
|---|---|
form_response.submitted | Waiver or form submitted |
voucher.sold | Gift card/voucher purchased |
voucher.redeemed | Voucher applied to booking |
Booking requests, inventory, sessions, shifts, the workshop, store products, surveys, promo codes, agents, bundles, the waitlist and memberships have events too. Webhook Events lists every one.
API Endpointsโ
| Method | Endpoint | Description | Scope Required |
|---|---|---|---|
GET | /v1/webhooks | List all webhooks | webhooks:read |
GET | /v1/webhooks/{id} | Get a single webhook | webhooks:read |
POST | /v1/webhooks | Create a new webhook | webhooks:write |
PATCH | /v1/webhooks/{id} | Update a webhook | webhooks:write |
DELETE | /v1/webhooks/{id} | Delete a webhook | webhooks:write |
GET | /v1/webhooks/events | List available events | webhooks:read |
POST | /v1/webhooks/{id}/regenerate-secret | Generate new secret | webhooks:write |
Webhook Payload Formatโ
All webhook payloads follow this structure:
{
"id": "evt_8fK2pQ7xLm4Vn9Rt3Wc1",
"event": "booking.created",
"created_at": "2026-01-15T12:00:00+00:00",
"data": {
// The record the event is about, e.g. the full booking object
}
}
id names the event and stays the same when a delivery is retried, so use it to skip a repeat. See Webhook Events for a full example.
A booking that holds both rentals and experiences fires one booking.created event (not one per type โ no fan-out, no double-counting). Its data.type is "mixed" and data.line_types is ["rental", "experience"]. Branch on line_types rather than type if you need to route the rental and experience halves separately. See Bookings โ Line Types.
Verifying Webhook Signaturesโ
Each webhook request includes an X-Webhook-Signature header. Always verify this signature:
$payload = file_get_contents('php://input');
$signature = hash_hmac('sha256', $payload, $your_webhook_secret);
if (hash_equals($signature, $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'])) {
// Valid - process the webhook
http_response_code(200);
} else {
// Invalid - reject the request
http_response_code(401);
}
Failure Handlingโ
- Webhooks must respond with
2xxstatus within 30 seconds - Failed deliveries are retried with exponential backoff
- After 10 consecutive failures, the webhook is automatically disabled
- Re-enable by updating
is_active: trueafter fixing your endpoint
Common Use Casesโ
Sync Bookings to External Calendarโ
curl -X POST "https://app.equipdash.com/api/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Calendar Sync",
"url": "https://your-app.com/webhooks/calendar",
"events": ["booking.created", "booking.updated", "booking.cancelled"]
}'
Send Notificationsโ
Subscribe to events and send SMS/email notifications:
{
"name": "Customer Notifications",
"url": "https://your-app.com/webhooks/notify",
"events": ["booking.created", "booking.no_show", "payment.received"]
}
Update Inventory Systemsโ
Keep external inventory in sync:
{
"name": "Inventory Sync",
"url": "https://your-app.com/webhooks/inventory",
"events": ["product.created", "product.updated", "booking.created"]
}
Best Practicesโ
- Always verify signatures - Never process unverified webhooks
- Respond quickly - Return 200 immediately, process async if needed
- Handle duplicates - Same event may be delivered more than once
- Use HTTPS - Always use HTTPS URLs in production
- Monitor failures - Check
failure_countregularly - Rotate secrets - Periodically regenerate webhook secrets
Related Resourcesโ
- Bookings - Booking event payloads
- Customers - Customer event payloads
- Products - Product event payloads
- Experiences - Experience event payloads