- Developers
- Webhooks
Webhooks
Get a signed POST on your server the moment something changes in a HowdyBell workspace.
A webhook endpoint is a URL on your server. When an event you picked happens, HowdyBell sends it a JSON POST. Endpoints are added by a workspace owner or manager in the app, and every delivery is signed so you can prove it came from HowdyBell.
Add an endpoint
- In HowdyBell, open Settings, then Integrations.
- In the API keys and webhooks card, under Webhooks, enter your Endpoint URL.
- Keep All events ticked, or untick it and pick the events you want.
- Click Add endpoint.
- Copy the signing secret shown once. You need it to check signatures.
Use Send test to queue a ping event to the endpoint.
The URL must be a public https address. Private and internal addresses are refused, and redirects are not followed.
What a delivery looks like
POST /hooks/howdybell HTTP/1.1
Content-Type: application/json
X-HowdyBell-Event: contact.created
X-HowdyBell-Delivery: 8812
X-HowdyBell-Signature: t=1791230400,v1=5f2a...c9
{
"id": 8812,
"event": "contact.created",
"created_at": "2026-10-05T14:30:00Z",
"data": { "...": "the record that changed" }
}
The shape of data depends on the event. Call Get sample payloads with an event name to see real examples from your workspace.
Check the signature
X-HowdyBell-Signature holds a Unix timestamp t and v1, the hex HMAC SHA-256 of "{t}.{raw body}" keyed with your signing secret. Compute it over the raw bytes you received, before any JSON parsing.
const crypto = require("crypto");
function isFromHowdyBell(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1 || "");
// Reject old timestamps too, so a captured request cannot be replayed later.
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && a.length === b.length && crypto.timingSafeEqual(a, b);
}
Retries
Answer with any 2xx status within 10 seconds. Anything else, a timeout or a redirect counts as a failed attempt. HowdyBell tries each delivery up to 5 times, waiting 1, 5, 30 and then 120 minutes between attempts. After the fifth failure the delivery is marked failed.
Deliveries can arrive more than once and out of order. Use X-HowdyBell-Delivery to skip duplicates.
Events
ping, location.created, location.updated, user.invited, contact.created, contact.updated, contact.deleted, opportunity.created, opportunity.stage_changed, task.created, task.completed, note.added, conversation.created, conversation.updated, message.received, message.sent, message.failed, workflow.run_started, workflow.run_finished, page.viewed, form.submitted, survey.submitted, quiz.submitted, trigger_link.clicked, review.received, review.replied, review_request.sent, review_request.clicked, video_testimonial.received, social_post.published, social_post.failed, social_post.approved, invoice.paid, payment.failed, contact.tag_added, contact.tag_removed, appointment.booked, appointment.cancelled.
ping is only sent by Send test.
Related
- REST hooks for automation platforms: subscribe and unsubscribe from code.
- Authentication