Skip to main content

Overview

Webhooks let you receive HTTP notifications when events happen in your workspace. Instead of polling the API, you can subscribe to specific events and Voyant will send a POST request to your endpoint.

Creating a subscription

1

Create a subscription

curl -X POST https://api.voyantcloud.com/v1/webhooks/subscriptions \
  -H "Authorization: Bearer $VOYANT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/voyant",
    "events": ["booking.created", "booking.updated"]
  }'
The response includes a secret - store it securely. You’ll need it to verify webhook signatures.
2

Verify signatures

Validate incoming webhooks using the X-Webhook-Signature header:
import crypto from "node:crypto"

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload, "utf8")
    .digest("hex")

  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex")
  )
}
3

Handle events

Return a 2xx status to acknowledge receipt. Non-2xx responses trigger retries.
app.post("/webhooks/voyant", (req, res) => {
  const signature = req.get("X-Webhook-Signature")

  if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(400).send("Invalid signature")
  }

  const event = req.get("X-Webhook-Event")
  // Handle the event...

  res.status(200).send({ ok: true })
})

Event types

Subscribe to specific events or use wildcards:
PatternDescription
booking.createdSingle event
booking.*All booking events
*All events

Available events

Bookings & Payments
  • booking.created, booking.updated, booking.cancelled, booking.confirmed
  • booking.payment.success, booking.payment.failed
  • payment.succeeded, payment.failed, payment.refunded
Products & Catalog
  • product.created, product.updated, product.deleted
  • product.published, product.archived
Inventory
  • departure.created, departure.updated, departure.capacity.changed
  • inventory.updated
Customers
  • customer.created, customer.updated, customer.deleted
Collections & Tags
  • collection.created, collection.updated, collection.deleted
  • tag.created, tag.updated, tag.deleted

Webhook headers

Every webhook request includes these headers:
HeaderDescription
X-Webhook-SignatureHMAC-SHA256 signature for verification
X-Webhook-EventEvent type (e.g., booking.created)
X-Delivery-AttemptAttempt number (1, 2, 3…)

Retries

Failed deliveries are retried with exponential backoff. Return 2xx to acknowledge, or 410 Gone to permanently disable the subscription.
Implement idempotency in your webhook handler - you may receive the same event more than once.

Managing subscriptions

# List subscriptions
curl https://api.voyantcloud.com/v1/webhooks/subscriptions \
  -H "Authorization: Bearer $VOYANT_API_KEY"

# Rotate secret (invalidates the old one)
curl -X POST https://api.voyantcloud.com/v1/webhooks/subscriptions/SUBSCRIPTION_ID/rotate-secret \
  -H "Authorization: Bearer $VOYANT_API_KEY"

# Delete subscription
curl -X DELETE https://api.voyantcloud.com/v1/webhooks/subscriptions/SUBSCRIPTION_ID \
  -H "Authorization: Bearer $VOYANT_API_KEY"

Next steps