Webhooks
Outbound webhooks let Insighto.ai notify your systems in real time when something happens — a conversation closes, a form is captured, an intent is matched. Use them to push data into your CRM, your data warehouse, or any internal system that needs to react to your assistant's traffic.
This page covers how to set up webhooks, the payloads you'll receive, and the honest truth about the current delivery guarantees (which are weaker than most teams expect — read the "Important caveats" section below).
Event types
| Event | When it fires |
|---|---|
conversation.closed | A conversation reaches a terminal state — call hangup, chat idle close, or agent termination. Includes the full transcript and billing details. |
conversation.updated | A conversation is updated but not yet closed — status changes, partial transcript flushes. |
captured_form.created | A form is captured inside a conversation. |
captured_form.updated | A previously captured form is edited (e.g. a missing field is filled in later). |
captured_intent.created | An intent is captured (used by the older intents pipeline). |
The exact event names appear verbatim in the event field of the payload.
Setting up a webhook
- Open Settings → Webhooks.
- Click Add webhook.
- Set:
- Endpoint — your URL. HTTPS strongly recommended for production.
- Name — a human label.
- Enabled — leave on.
- Save. A secret is generated and stored on the webhook record (see the verification section below — the secret isn't currently used for HMAC signing).
A webhook fires when any of its subscribed events is generated for an assistant whose owner created the webhook.
Payload shape
Every payload follows this envelope:
{
"id": "01902b1f-9e1f-7c2a-9e23-3f8c0b9a2c4d",
"object": "event",
"event": "conversation.closed",
"created_at": "2026-05-14 09:32:11",
"data": {
"conversation_id": "01902b1d-...",
"assistant_id": "01902b1c-...",
"transcript": [
{ "role": "user", "content": "..." },
{ "role": "assistant", "content": "..." }
],
"billing_details": {
"billing_type": "voice",
"billing_used": "wallet",
"call_duration": 312,
"voice_multiplier": 1,
"llm_model": "gpt-4o-mini",
"price_per_minute": 0.06,
"utilized_wallet_balance": 0.312
},
"conversation_billed_to": "wallet",
"intent_name": "qualified_lead"
}
}
The id field is unique per delivery — use it to de-dupe in your handler.
Delivery flow
Important caveats (read this)
The current implementation is intentionally simple. Be aware of these gaps before you depend on webhooks for anything critical:
- No retries. A delivery is attempted exactly once. If your endpoint is down, returns 5xx, or times out, the event is logged with the error status and not retried. Don't rely on webhooks for at-least-once delivery.
- No HMAC signature. The current implementation posts a plain JSON body with no signature header. The webhook secret stored on your record isn't currently sent with deliveries.
- No queue. Deliveries fire inline from the event that triggered them. If the platform restarts at the exact moment between event creation and HTTP send, the event is lost.
If you need at-least-once delivery, idempotency guarantees, or a verified signature, these are known gaps on the roadmap. Talk to support.
How to verify authenticity today
Without an HMAC signature, the practical mitigations are:
- IP allowlist. Restrict your endpoint to accept requests only from Insighto's egress IPs. Contact support for the current list.
- Hard-to-guess URL path. Embed a long random token in your webhook URL:
https://your.api/webhooks/insighto/<random-token>. Treat the path as a shared secret. - Re-fetch the canonical record. For high-stakes flows, treat the payload as a notification only and call
GET /api/v1/conversation/{id}from your handler to re-fetch the truth from Insighto's API.
A reference HMAC verifier (for when signing ships):
import hmac, hashlib
def verify(payload_bytes: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
payload_bytes,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature_header)
Four business use cases
B2B SaaS — qualified-lead Slack alert. An analytics startup posts a Slack message every time conversation.closed arrives with intent_name == qualified_lead. The Slack message includes the lead's company, captured email, and the conversation transcript link. Outcome: SDRs see leads land in real time.
Healthcare — captured form to compliance. A telehealth company points its captured_form.created webhook at an internal compliance review queue. Every form submission (intake, consent, prescription request) lands in the queue automatically. They protect the endpoint with an IP allowlist.
E-commerce — refund queue. A meal-kit company filters conversation.closed events for intent_name == refund_requested and pushes them into a finance review tool. The webhook handler immediately returns 200 and processes async to keep handler latency low.
Real estate — lead capture into HubSpot via Zapier. A brokerage points the conversation.closed webhook at a Zapier hook URL with the secret embedded in the path. The Zap parses the transcript, creates a HubSpot contact, and assigns to the on-call agent.
Logs
Every delivery attempt is recorded. The webhook detail page shows:
- Timestamp + event name
- Full request body sent
- Response code returned by your endpoint
- Response body (string-cast)
Click any row for the full request/response. Useful when debugging "the webhook didn't fire" complaints.
Tips
- Acknowledge fast. Return 200 quickly and process heavy work async. Since there are no retries, holding the HTTP connection open doesn't help you anyway.
- De-dupe on
id. Each delivery has a uniqueid. In normal operation you'll see each event once, but it's good hygiene. - Test locally with a tunnel. Use ngrok or Cloudflare Tunnel to expose your local endpoint during development.
Inbound webhooks
To send data into Insighto from external systems (LeadConnector, Facebook Messenger, Instagram, Telegram, Twilio voice), each channel has its own inbound webhook pattern with provider-specific signing. See the Channel Setup section.
Where to next
- Webhook payloads reference — exact field-by-field shapes per event.
- Intents library — what populates
intent_nameon a conversation. - Forms library — what populates the
captured_formevents.