Webhooks

We POST a signed JSON event to your HTTPS endpoint when something happens in any product.

Delivery

  • Body: { "id", "type", "timestamp", "api_version", "org_id", "data" }. id equals the webhook-id header and stays the same on retries and replays: use it to ignore duplicates.
  • Answer with any 2xx within 10 seconds. Do slow work after answering. Redirects are not followed.
  • Retries after a failure: 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 10 h (with jitter), 8 attempts in total. Then the delivery is marked failed and you can replay it from the dashboard.
  • HTTP 410 Gone turns the endpoint off at once; 20 failed deliveries in a row turn it off too. Turning it back on resets the counter.
  • Only public HTTPS addresses are called (no private networks, no cloud metadata addresses), and the address is checked again on every delivery.
  • Order is not guaranteed. Use timestamp, or fetch the current object from the API.

Verify the signature

We follow Standard Webhooks. Compute HMAC-SHA256 over webhook-id.webhook-timestamp.body with the base64 part of your whsec_ secret, and compare it with each v1, value in webhook-signature. Reject timestamps older than 5 minutes. While you rotate a secret, both the new and the old secret sign each delivery.

import { createHmac, timingSafeEqual } from "node:crypto";

// Use the RAW request body (before JSON parsing).
export function verify(secret, headers, rawBody) {
  const id = headers["webhook-id"], ts = headers["webhook-timestamp"], sigs = headers["webhook-signature"];
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) throw new Error("too old");
  const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
  const expected = createHmac("sha256", key).update(`${id}.${ts}.${rawBody}`).digest();
  const ok = sigs.split(" ").some((s) => {
    const got = Buffer.from(s.split(",")[1] ?? "", "base64");
    return got.length === expected.length && timingSafeEqual(got, expected);
  });
  if (!ok) throw new Error("bad signature");
  return JSON.parse(rawBody);
}

Webhook tester

Paste a delivery from your logs to check its signature. Runs in your browser only.

Event catalogue

Subscribe to exact events, a whole product (lead.*) or everything (*). Also as JSON: /api/v1/events.

Contacts

contact.created
A contact was added through the API.
contact.updated
A contact was changed through the API.
contact.deleted
A contact was deleted through the API.

AI Front Desk

message.received
A customer message arrived on any channel.
message.created
A message was added to a conversation.
message.queued
An outgoing message was queued for delivery.
message.sent
An outgoing message was sent by the channel provider.
message.failed
An outgoing message could not be delivered.
message.bounced
An email bounced.
channel.opted_out
A person opted out of a channel (STOP, unsubscribe).
booking.created
A booking was created through the API.
booking.updated
A booking was changed through the API.
booking.requested
A booking was requested by the assistant or a customer.
booking.reminder_queued
A booking reminder was queued.
booking.reminder_sent
A booking reminder was sent.
booking.reminder_skipped
A booking reminder was skipped.
calendar.external_cancelled
A booking was cancelled in the connected calendar.
calendar.external_moved
A booking was moved in the connected calendar.
calendar.external_conflict
A connected calendar has a conflicting event.
knowledge_article.created
A knowledge article was added through the API.
knowledge_article.updated
A knowledge article was changed through the API.
knowledge_article.deleted
A knowledge article was deleted through the API.

AI Revenue Engine

lead.created
A new lead was created.
lead.updated
A lead was changed through the API.
lead.stage_changed
A lead moved to another pipeline stage.
lead.assigned
A lead got a new owner.
followup.enrolled
A lead was enrolled in a follow-up sequence.
followup.drafted
A follow-up message was drafted.
followup.stopped
A follow-up sequence stopped for a lead.
campaign.created
An old-lead campaign was created.

AI Voice Workforce

voice.call_started
A phone call started.
voice.call_ended
A phone call ended (summary, outcome).
voice.message_taken
The voice agent took a message.
voice.transfer_requested
A caller asked to speak to a person.
voice.dial_requested
An outbound campaign target is ready to dial.
voice.campaign_created
An outbound call campaign was created.
voice.dnc_added
A number was added to the do-not-call list.

AI Customer Experience

ticket.created
A support ticket was created.
ticket.updated
A ticket was changed through the API.
ticket.status_changed
A ticket changed status.
ticket.assigned
A ticket got a new assignee or priority.
ticket.merged
A ticket was merged into another.
ticket.sla_breached
A ticket missed its SLA target.
ticket.limit_reached
The monthly ticket limit was reached.
csat.sent
A CSAT survey was sent.
csat.received
A CSAT score was received.
review.received
A review was added.
review.negative
A negative review needs attention.

AI Sales Workforce

prospect.created
A prospect was added through the API.
prospect.updated
A prospect was changed through the API.
sales.imported
Prospects were imported.
sales.enrolled
A prospect was enrolled in an outbound sequence.
sales.drafted
An outbound step was drafted.
sales.message_sent
An outbound message was sent.
sales.reply_logged
A prospect replied.
sales.reply_interested
A prospect replied with interest.
sales.reply_handed_over
A reply was handed over to a person.
sales.meeting_booked
A meeting was booked with a prospect.
sales.meeting_scheduled
A meeting was scheduled.
sales.meeting_held
A meeting took place.
sales.meeting_no_show
A prospect did not attend a meeting.
sales.meeting_cancelled
A meeting was cancelled.
sales.enrolment_stopped
An outbound sequence stopped for a prospect.
sales.opted_out
A prospect opted out.
sales.suppression_added
An address or domain was added to do-not-contact.

AI Business Intelligence

bi.insight_created
An alert rule produced an insight.
bi.digest_ready
The weekly digest is ready.
bi.dataset_imported
A dataset was imported.
bi.dashboard_created
A dashboard was created.
bi.question_asked
Someone asked a question about the data.

AI Back-Office Workforce

back_office.document_uploaded
A document was uploaded.
back_office.extraction_done
A document was read (fields extracted).
back_office.document_approved
A document was approved.
back_office.document_rejected
A document was rejected.
back_office.approval_requested
An approval step is waiting.
back_office.record_approved
A record (bill, invoice, expense) was approved.
back_office.record_rejected
A record was rejected.
back_office.record_status_changed
A record changed status (scheduled, paid).

AI Content Studio

content.post_created
A post was created through the API.
content.post_updated
A post was changed through the API.
content.plan_generated
A content plan was generated.
content.post_submitted
A post was submitted for approval.
content.post_approved
A post was approved.
content.post_changes_requested
Changes were requested on a post.
content.post_scheduled
A post was scheduled.
content.post_published
A post was marked as published.
content.ideas_refreshed
Content ideas were refreshed.
content.review_consent_withdrawn
A customer withdrew consent to feature a review.