API reference
Outgoing webhooks
Glozr fires outgoing webhooks when interesting things happen in your workspace. Configure them in /app/integrations/webhooks; every payload is HMAC-signed so you can verify it actually came from Glozr.
Current surface
The v1 webhook surface supports a single event type: lead.captured. Delivery is single-attempt — no automatic retries — and every payload is signed with HMAC-SHA256. Conversation-level events are on the roadmap but not yet available.
Configuration
Each webhook subscription needs:
- A destination URL. HTTPS is strongly recommended.
- An event type (currently only
lead.captured). - An auto-generated signing secret, used to verify every delivery.
- An active toggle so you can pause deliveries without deleting the subscription.
Request headers
Every dispatch carries two headers:
Content-Type: application/jsonX-Pitchbar-Signature— timestamped HMAC, formatt=<unix_ts>,v1=<hex_sig>.
Verifying the signature
The signed string is "{timestamp}.{raw_request_body}", hashed with HMAC-SHA256 using your signing secret.
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const [tPart, sigPart] = header.split(',');
const t = Number(tPart.split('=')[1]);
const sig = sigPart.split('=')[1];
// Reject anything older than 5 minutes
if (Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(sig, 'hex')
);
}
Two things to keep in mind: always use a constant-time comparison (Node's timingSafeEqual, PHP's hash_equals, etc.), and reject any delivery whose timestamp is more than 5 minutes off to defeat replay attacks.
Delivery pattern
Webhooks are a single HTTP POST with a 5-second timeout. There is no built-in retry, so build your receiver defensively:
- Return
2xxas quickly as possible. Acknowledge first, process later. - Push the work into your own queue so a slow downstream system doesn't time out the webhook.
- Deduplicate on
occurred_at+ lead ID in case Glozr fires the same event twice. - For critical data, periodically reconcile with the admin leads endpoint.
Event payload
The lead.captured payload includes:
event—"lead.captured".occurred_at— ISO-8601 timestamp.lead_idandagent_id.conversation_id— the conversation that produced the lead.fields— captured form fields:name,email,phone, plus any custom fields you configured.
Roadmap
Planned for upcoming releases:
- Conversation-level events (
conversation.started,conversation.escalated). - Per-delivery IDs in headers, for safer deduplication.
- At-least-once retry semantics with exponential backoff and dead-letter delivery for permanent failures.