8. Integrations — Outbound Webhooks
Outbound webhooks let NoviaMind notify your own systems the moment your CRM data changes — instead of you polling the API. Typical uses: triggering an n8n / Make / Zapier workflow when a new prospect is captured, or keeping an in-house tool in sync.
Access them from Integrations → Outbound Webhooks in the CRM section.
8.9 Available Events
| Event | Sent when |
|---|---|
lead.created | A prospect is created |
lead.updated | A prospect is updated |
property.created | A property is created |
property.updated | A property is updated |
realtor.created | A realtor is created |
realtor.updated | A realtor is updated |
A webhook subscribes to one or more events — only those trigger a delivery to your URL.
8.10 Creating a Webhook
- Go to Integrations → Outbound Webhooks
- Click on "Add webhook"
- Enter your callback URL (must be
https://in production;http://is accepted only for local testing, e.g. an ngrok tunnel) - Optionally add a description (e.g. "n8n production workflow")
- Select the events to subscribe to
- Click on "Save"
⚠️ Store the signing secret immediately. After creation, NoviaMind shows the secret (
whsec_...) once and only once. Every later view shows it masked. If you lose it, delete the webhook and create a new one.
💡 URLs pointing to private or internal network addresses are rejected for security reasons.
8.11 What Your Endpoint Receives
Each delivery is an HTTP POST with a JSON body:
And these headers:
| Header | Content |
|---|---|
X-Webhook-Id | Unique delivery ID (also the id in the body) |
X-Webhook-Event | Event name (e.g. lead.created) |
X-Webhook-Signature | sha256=<hex> — HMAC-SHA256 signature of the raw body |
data format per entity
data is not a curated response DTO — it's the full lead/property/realtor row as stored, so it can carry more fields than are documented below (treat unknown fields as forward-compatible, don't reject on them) and every nullable field you don't use is simply null.
lead.created / lead.updated — data is the lead. Real capture (from an AI-agent call, secrets/PII shortened, notes and the AI data-collection blocks in custom_fields / raw_data truncated for length — in practice notes is the full call summary and custom_fields.* has one entry per configured collection field):
💡 Internal call-tracking identifiers are stripped before this leaves NoviaMind — you'll never see a
conversation_idsfield, even though it's a real column on the underlying record.💡
custom_fieldsandraw_data.data_collection_resultsboth come from the AI's field extraction and largely overlap (raw_datais the extraction as originally captured;custom_fieldsis what's actually persisted to the lead). Each entry carriesvalue,rationale(why the AI extracted that value), anddata_collection_id— some entries also carry ajson_schemablock describing the field's expected type/enum.valueis frequentlynullwhen the AI found nothing to extract for that field on the call.
property.created / property.updated — data is the property:
realtor.created / realtor.updated — data is the realtor:
💡
webhook.testdeliveries (from the "Send test" button) don't match any of the shapes above —datais just{ "message": "This is a test webhook delivery from NoviaMind." }.
Verifying the signature
Compute an HMAC-SHA256 of the raw request body bytes (not the re-serialized/parsed object — key order or whitespace differences will make the signature not match) with your signing secret, and compare it to the X-Webhook-Signature header using a constant-time comparison. Node/Express example, assuming the route has raw-body access (e.g. express.raw({ type: 'application/json' }) mounted only on this route, before any JSON body parser):
💡 In n8n, the Webhook node gives you the raw body via the node's binary/raw data option — verify it in a Code node with the same logic before trusting
event.data, or simply keep the URL secret if signature verification isn't required for your use case.
Your endpoint should respond with a 2xx status within 10 seconds. Any other response counts as a failure.
8.12 Testing a Webhook
Click on "Send test" on a webhook row. NoviaMind sends a synthetic webhook.test event, signed exactly like a real delivery, and shows you the HTTP status your endpoint returned — ideal for validating your n8n workflow or signature check before going live.
8.13 Retries, Failures, and Auto-Disable
- Each event is delivered with up to 5 attempts and exponential backoff.
- The webhook row shows the last delivery status and the number of consecutive failures.
- After 20 consecutive failures, the webhook is automatically disabled so a dead URL stops consuming delivery attempts. Fix your endpoint, then click "Re-enable".
- Any successful delivery resets the failure counter.
Delivery history
Click on "History" to see the last deliveries (up to 50, retained for 30 days): timestamp, event, HTTP status, and attempt number. Only outcome metadata is stored — never the payload itself.
8.14 Managing Webhooks
| Action | Who can do it |
|---|---|
| View webhooks and history | All team members |
| Create, edit, test, enable/disable | Admins and regular members |
| Delete | Admins only |
- Enable / Disable: pause deliveries without losing the configuration (the switch on each row).
- Edit: change the URL, description, or subscribed events at any time. The signing secret never changes.
- Rotate the secret: delete the webhook and create a new one.
💡 Developers can find the full API reference (endpoints, schemas, signature details) in the API documentation linked from the webhooks dialog.