How do URBLD webhooks work?
Register an HTTPS endpoint and select the events you want to receive. URBLD POSTs a JSON payload for every event with an HMAC-SHA256 signature in the X-URBLD-Signature header. Verify the signature, respond with 2xx within 10 seconds, and URBLD marks the delivery successful. Failed deliveries retry with exponential backoff for 24 hours.
Payload format
POST https://your-app.example.com/webhooks/urbld
{
"id": "evt_01HXYZ...",
"type": "job.completed",
"created_at": "2026-07-04T15:32:11Z",
"org_id": "org_01HABCDE",
"data": {
"job_id": "job_01HXYZ",
"lifecycle_number": "L-1042",
"customer_id": "cus_01HXYZ",
"completed_at": "2026-07-04T15:32:00Z"
}
}Verifying signatures
verify.ts
import crypto from "node:crypto";
export function verifyUrbldWebhook(rawBody: string, signature: string, secret: string) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(signature, "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Available events
| Event | Fired when |
|---|---|
| lead.created | A new lead was captured (form, phone, chat, or agent). |
| lead.qualified | A lead was qualified and ready for scheduling. |
| appointment.booked | An appointment was booked on the calendar. |
| appointment.rescheduled | An appointment moved to a new time. |
| appointment.cancelled | An appointment was cancelled. |
| estimate.sent | An estimate was delivered to a customer. |
| estimate.approved | A customer approved an estimate. |
| contract.signed | All parties signed a contract package. |
| job.created | A signed contract was converted to a job. |
| job.completed | A job reached completed state. |
| invoice.issued | An invoice was issued. |
| invoice.paid | An invoice was fully paid. |
| payment.received | A payment was captured. |
| message.received | An inbound SMS or email arrived in the unified inbox. |
Best practices
- Respond with a 2xx status within 10 seconds. Do heavy work asynchronously.
- Store the
idand treat repeated deliveries as idempotent. - Verify signatures on every request — never trust the payload alone.
- Use a dedicated URL per environment (staging, production) so replayed events do not cross environments.
FAQ
Frequently Asked Questions
Straight answers about how URBLD runs the business end-to-end.