Developer docs

Send qualified leads to your CRM.

Burt can push every qualified lead to a URL you choose, the moment it becomes a lead you pay for. Connect it to Zapier, Make, or your own system to land cases in Clio, Filevine, Litify, Lead Docket or anything else.

Set it up

The firm owner or a manager can do this. It takes about two minutes.

  1. In your Burt dashboard, open Settings → Integrations.
  2. Paste your endpoint URL. It must start with https://. In Zapier, use a Webhooks by Zapier → Catch Hook trigger and paste its URL.
  3. Click Save. Burt shows your signing secret (it starts with whsec_) once. Copy it into your receiver now. If you lose it, click Rotate secret to get a new one; the old one stops working immediately.
  4. Click Send test event. Burt sends a sample lead (marked "livemode": false) and shows how your endpoint answered.

When it fires

One event type today: lead.qualified.

It is sent when a lead becomes billable: the case qualified and it was released, either because the claimant verified their phone number or because someone on your team clicked Confirm lead in the inbox. A held (unverified) lead is not sent until it is released. A duplicate of a lead you already received is not sent again. Leads that arrived before you saved the webhook, or while it was turned off, are not sent.

The payload

A POST with a JSON body. Every field is listed below; new fields are only ever added, with a new apiVersion date.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: Burt-Webhooks/1.0 (+https://hiburt.com/webhooks.html)
X-Burt-Event: lead.qualified
X-Burt-Event-Id: evt_6b1f…
X-Burt-Delivery-Attempt: 1
X-Burt-Signature: t=1791201600,v1=5f2c…

{
  "id": "evt_6b1f2a0e-…",
  "type": "lead.qualified",
  "apiVersion": "2026-10-05",
  "created": "2026-10-05T16:00:00.000Z",
  "livemode": true,
  "data": {
    "case": {
      "id": "3c9d…",
      "createdAt": "2026-10-05T15:41:12.000Z",
      "qualifiedAt": "2026-10-05T15:58:40.000Z",
      "tier": 1,
      "caseType": "car",
      "summary": "Rear-ended at a red light on 10/2; neck and back pain; ER visit same day.",
      "claimant": {
        "firstName": "Jane",
        "lastName": "Doe",
        "name": "Jane Doe",
        "phone": "+15551234567",
        "email": "jane@example.com"
      },
      "dashboardUrl": "https://app.hiburt.com/cases/3c9d…"
    }
  }
}
"id"
The event id. It stays the same on every retry of this lead, so use it to ignore duplicates.
"type"
lead.qualified (or webhook.test for a test event).
"apiVersion"
The payload version date.
"created"
When the event was created (ISO 8601, UTC).
"livemode"
false only on a test event from the dashboard; test events carry sample data, never a real lead.
"data"
Holds "case", the lead.
"case" fields
"id" (the Burt case id), "createdAt", "qualifiedAt", "tier" (1 = strongest, up to 4, or null), "caseType" (one of: car, truck, motorcycle, rideshare, pedestrian_bicycle, boating_accident, slip_and_fall, premises_liability, dog_bite, workplace, product_liability, medical_malpractice, nursing_home_abuse, wrongful_death, or null), "summary" (Burt’s written case summary, or null), "claimant", "dashboardUrl" (opens the case in Burt; your team must be signed in).
"claimant" fields
"firstName", "lastName", "name", "phone" (E.164, for example +15551234567), "email" (lowercase). Any of them can be null.

Verify the signature

Every request carries X-Burt-Signature: t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256, keyed with your signing secret, over the string <t>.<raw request body>. Check it before you trust the request:

  1. Read the raw body bytes. Do not parse and re-serialize the JSON first; that changes the bytes and the check fails.
  2. Compute HMAC-SHA256 of t + "." + rawBody with your secret, hex-encoded, and compare it to v1 with a constant-time comparison.
  3. Reject the request if t is more than 5 minutes from your clock (replay protection).
// Node.js (Express): app.post('/burt', express.raw({ type: 'application/json' }), handler)
const crypto = require('crypto');

function verifyBurt(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.trim().split('=')));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;          // replay window
  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  const got = Buffer.from(parts.v1 || '', 'hex');
  const want = Buffer.from(expected, 'hex');
  return got.length === want.length && crypto.timingSafeEqual(got, want);
}
# Python
import hmac, hashlib, time

def verify_burt(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.strip().split("=", 1) for p in header.split(","))
    t = int(parts.get("t", "0"))
    if abs(time.time() - t) > 300:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Retries & duplicates

Answer with any 2xx status within 10 seconds to acknowledge. Anything else (a 4xx, a 5xx, a timeout, a redirect) counts as a failure and Burt retries after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours: eight attempts over about two days. After that the delivery is marked failed; you can see every delivery and its result under Settings → Integrations.

Delivery is at least once: in rare cases (a network cut after you answered) you may receive the same event twice. De-duplicate on the event "id" (also in the X-Burt-Event-Id header). Process the lead asynchronously if your CRM call is slow, and answer 200 first.

Endpoint rules

  • HTTPS only, with a valid certificate. No usernames or passwords in the URL.
  • The address must be on the public internet. Private, loopback and cloud-internal addresses are refused.
  • Redirects are not followed. Give Burt the final URL.
  • Burt does not read or store your response body.
  • Treat the endpoint URL and the signing secret like passwords. Rotate the secret from the dashboard if it may have leaked.

Questions?

Email support@hiburt.com. We’re happy to help you wire up your CRM.

Open your dashboard All integrations