Guides
A step-by-step guide to configuring post-call webhooks in Thoughtly so every AI voice agent conversation automatically updates your CRM with structured call outcomes, lead qualification data, and transcript summaries.
Last updated
Every AI voiceAI voiceAn artificially generated, natural-sounding voice produced by a TTS model. Thoughtly supports a library of AI voices and brand-specific cloning. agent call generates valuable data: what the prospect said, whether they qualified, what appointment they booked, what objections they raised. The question is whether that data reaches your CRMCRMThe system of record for leads, contacts, deals, and activity. Thoughtly reads from and writes to your CRM continuously. in seconds or sits stranded until someone manually exports it.
Post-call webhooks solve this by pushing structured call outcomes to your CRM, data warehouse, or downstream systems the moment a conversation ends. No polling, no batch imports, no stale pipeline data.
This guide walks through setting up post-call webhooks in Thoughtly using the On Call Completed automation trigger and the Send Webhook step. You will learn how to configure the trigger, shape the payload, secure the endpoint, and handle errors—with real patterns for HubSpot, Salesforce, and GoHighLevel.
Open Tools → Automations in the Thoughtly dashboard and create a new automation. When prompted to select a trigger, choose Thoughtly → On Call Completed.
This trigger fires after every call ends for the agents you select. You have two scope options:
For most CRM webhook setups, start with Specific Agents so you can tailor the payload to that agent's variableVariableA named value the voice agent stores during a conversation — caller name, intent, qualifying answers — and uses to drive routing and post-call actions. structure. Expand to All Agents once your webhook receiver handles variable payloads gracefully.
After selecting the trigger, click the Output tab. If you have completed calls for the selected agent, click Refresh to load a real payload sample. If no calls exist, Thoughtly generates a mock response.
The On Call Completed trigger provides rich call data including:
The transcriptTranscriptThe text record of a voice conversation, used for review, training, compliance audit, and search. structure is especially useful. Each entry is an object, not a flat string:
[
{
"transcript": "Hi, I'm calling about the home insurance quote I requested.",
"speaker": "user",
"createdAt": "2026-06-12T14:22:05.330Z"
},
{
"transcript": "I'd be happy to help with that. Can I confirm your zip code?",
"speaker": "ai",
"createdAt": "2026-06-12T14:22:12.120Z",
"step": 2,
"node_id": "node_qualify_zip"
}
]Copy the field paths you need for your CRM. Common mappings include:
| Thoughtly field | Typical CRM field | Example value |
|---|---|---|
| trigger.payload.contact.phone | Phone / Lead phone | +18005551234 |
| trigger.payload.variables.intent | Lead intent / Interest | home_insurance_quote |
| trigger.payload.variables.zip_code | Zip / Service area | 90210 |
| trigger.payload.duration | Call duration (seconds) | 187 |
| trigger.payload.outcome | Disposition / Status | qualified |
| trigger.payload.transcript | Call notes / Activity log | [structured array] |
Click Next Step on the trigger node and add a Send Webhook step under the Webhook and Utility category.
Configure these fields:
X-API-Token or Authorization header so your receiver can verify the request is legitimate.A typical webhook body for an insurance lead CRM update looks like this:
{
"event_type": "call_completed",
"event_id": "{{ trigger.payload.call_id }}",
"phone": "{{ trigger.payload.contact.phone }}",
"outcome": "{{ trigger.payload.outcome }}",
"duration_seconds": {{ trigger.payload.duration }},
"intent": "{{ trigger.payload.variables.intent }}",
"zip_code": "{{ trigger.payload.variables.zip_code }}",
"policy_type": "{{ trigger.payload.variables.policy_type }}",
"qualified": {{ trigger.payload.variables.qualified }},
"transcript_summary": "{{ steps.ai_summary.result }}",
"timestamp": "{{ trigger.payload.completed_at }}"
}Raw transcripts are long. Most CRM fields have character limits, and sales reps skim. Insert an AI step between the trigger and the Send Webhook to generate a concise call summary.
Add an AI → Custom Prompt step before Send Webhook. Configure it with:
{{ trigger.payload.transcript }} (the full structured transcript)The output of this step becomes available as a variable you can include in the webhook body. Map it as the transcript summary field in your CRM instead of dumping the raw transcript.
Not every call should trigger the same CRM action. A qualified insurance lead needs a different pipeline update than a hang-up or wrong number.
Insert a Conditions → If/Else step after the AI summary:
trigger.payload.variables.qualified equals true → route to a Send Webhook step that creates or updates a deal/opportunity in your CRMFor more granular routing, use a Switch step. Common branches for consumer lead funnels:
| Outcome | CRM action | Example webhook path |
|---|---|---|
| Qualified + appointment booked | Create deal, update stage to 'Booked' | /api/deals/create |
| Qualified + no appointment | Create deal, stage 'Needs follow-up' | /api/deals/create |
| Not qualified | Add note to contact, tag 'DQ' | /api/contacts/note |
| Voicemail left | Tag 'Voicemail', schedule retry | /api/contacts/tag |
| No answer / hang-up | Tag 'No answer', schedule retry | /api/contacts/tag |
An open webhook URL is an invitation for junk data in your CRM. Lock it down:
X-API-Token header in the Send Webhook step. Your receiver checks this header and rejects requests without it.event_id (call ID) to deduplicate. If your receiver sees the same event_id twice, skip the duplicate.In Thoughtly, you can also enable webhook verification under Settings → Developer. Generate an API key there and send it in the request header for an additional verification layer.
Thoughtly automations start in Draft mode, which means they will not execute on real events until you activate them.
Thoughtly's native HubSpot integration supports direct contact creation and updates without webhooks. But if you need to push call data into custom HubSpot workflows or objects, use the Send Webhook step to hit HubSpot's WorkflowWorkflowAn automated, multi-step process — usually triggered by an event (form fill, new lead) and orchestrating one or more voice / SMS / email actions. webhook URL or the Contacts API.
Common pattern: On Call Completed → AI Summary → If/Else (qualified?) → Send Webhook to HubSpot's Update Contact endpoint with call notes, outcome, and deal stage. Alternatively, use Thoughtly's built-in HubSpot steps (Create Contact, Update Contact, Search Contact) directly in the automation instead of a raw webhook.
For Salesforce, you can either use Thoughtly's native Salesforce steps (Execute SOQL Query, Create Object, Update Object) or send webhooks to a custom Apex REST endpoint or a Salesforce Flow webhook trigger.
A typical pattern for insurance or mortgage leads: On Call Completed → AI Extract Fields (pull structured data from transcript) → Conditions (qualified lead vs. not) → Salesforce Create Object (Task with call summary) or Send Webhook to a Salesforce-connected middleware.
GoHighLevel users can use Thoughtly's native GHL integration (Create Contact, Update Contact, Create Note) or push data via webhook to a GHL workflow trigger. The webhook approach is useful when you need GHL's internal automation engine to continue the sequence—for example, moving a contact to a new pipeline stage and triggering a follow-up SMS drip.
Track these metrics to confirm your post-call webhooks are working and delivering value:
| Metric | Target | How to measure |
|---|---|---|
| Webhook delivery rate | >99% | Monitor 200 vs. non-200 responses in your endpoint logs |
| CRM record freshness | <60 seconds post-call | Compare call end timestamp to CRM record updated_at |
| Duplicate record rate | <0.5% | Count CRM records with the same call ID / event_id |
| Field completeness | >95% of expected fields populated | Audit a sample of 20 CRM records weekly |
| Rep response time to qualified leads | <5 minutes from call end | Measure time from CRM deal creation to first rep action |
If your webhook delivery rate drops below 99%, check your endpoint's response time (should be under 5 seconds) and error logs. Thoughtly retries on 429 but does not retry on 400 or 500 errors, so those represent permanent data loss unless you build a fallback.
Yes. Add multiple Send Webhook steps in the same automation, each pointing to a different URL. For example, one webhook to your CRM, another to your data warehouse, and a third to a Slack channel via an incoming webhook URL. Each step runs sequentially in the automation flow.
If your endpoint returns a non-200 response, the Send Webhook step fails. Thoughtly automatically retries once on 429 (rate limit) responses, respecting the Retry-After header. For 400 or 500 errors, there is no automatic retry. Build a fallback branch in your automation: route failures to a Slack notification, a logging spreadsheet, or a backup endpoint so you can replay the data manually.
Use On Call Completed for new setups. The Webhook API subscriptions (POST /webhooks/subscribe) are a lower-level interface from the Developer page. On Call Completed gives you conditional logic, AI processing steps, multi-CRM routing, and error handling—all in a visual automation builder. The API subscriptions are useful when you need raw event streaming to an infrastructure-level consumer, but most CRM integrations benefit from the automation approach.
Yes. Use the Specific Agents scope on the trigger to limit which agents fire the automation. Then add Conditions steps to filter by outcome, duration, or any captured variable. For example: only send a webhook for calls longer than 60 seconds where the outcome is "qualified."
Not always. Thoughtly has native automation steps for HubSpot, Salesforce, GoHighLevel, Keap, Zoho CRM, and Pipedrive that can create contacts, update records, and add notes directly. Use those native steps when they cover your use case. Use Send Webhook when you need to push data to a system Thoughtly does not have a native integration for, or when your CRM workflow requires a webhook trigger to continue an internal automation sequence.
Thoughtly Automations documentation — full reference for triggers, steps, and automation patterns.
Thoughtly Automation Triggers — On Call Completed, Incoming Webhook, and integration triggers.
Thoughtly Automation Actions and Steps — Send Webhook, AI, Conditions, CRM steps, and more.
Attributes vs Metadata in Thoughtly — understanding data persistence for contacts and calls.
Thoughtly Integrations — 200+ native integrations including Salesforce, HubSpot, and GoHighLevel.
How to Sync AI Conversations Back to HubSpot — step-by-step HubSpot sync guide on the Thoughtly blog.
How to Sync AI Conversations Back to Salesforce — step-by-step Salesforce sync guide on the Thoughtly blog.