Connect a Webhook (A–Z Guide)
With webhooks, Sally can instantly send data to other tools as soon as something happens — for example, sending a meeting summary directly to your automation platform the moment it’s ready.
This guide explains webhooks from scratch and walks you through a complete example.
Quick Navigation
- What is a webhook (simple explanation)?
- Prerequisites
- Create a webhook URL in your tool
- Create a webhook in Sally
- JSON body & field reference
- Test the connection & view logs
- FAQ & Troubleshooting
1. What is a webhook (simple explanation)?
A webhook is essentially an internet address (URL) provided to you by another tool or system (e.g., Zapier, Make, n8n, Power Automate, or your own backend).
Whenever something specific happens in Sally — for example, when a summary is created — Sally automatically sends a POST request to that URL.
Comparison:
- API = you actively request data from another system.
- Webhook = the system automatically sends you data when something happens.
Typical webhook use cases:
- Automatically send summaries to an automation platform
- Create tasks in your workflow tools (Zapier, Make, n8n, Power Automate)
- Trigger backend actions when a meeting ends
2. Prerequisites
To connect Sally to another tool via webhook, you need:
-
Access to the target tool
Example: Zapier, Make, n8n, Power Automate, or a custom backend.infoWithout an account in the target tool, you cannot create a webhook endpoint.
-
Permission to create or access a webhook URL
This URL always comes from the target tool.- In tools like Zapier, Make, n8n, Power Automate → you find it inside the workflow setup.
- In custom systems → developers usually provide it.
infoCheck whether your role (e.g., “Admin” or “Owner”) is allowed to create webhooks.
-
A Sally account with integration permissions
- Personal webhooks: Always available
- Organization-wide webhooks: Only with the right permissions
The webhook URL always comes from the target system — never from Sally.
Without it, Sally has nowhere to send data.
3. Create a webhook URL in your tool
The steps differ depending on your system but the principle is always the same:
- Open your target tool (e.g., Zapier, Make, n8n, Power Automate, custom system).
- Create an incoming webhook (sometimes called “Listener URL”, “Trigger URL”, or “Endpoint”).
- Copy the generated Webhook URL.
If unsure, search your tool’s documentation for “create webhook” + tool name.
4. Create a webhook in Sally
Once your target tool has generated a webhook URL, you can configure it in Sally. The new webhook integration gives you full control over authentication, headers, and the webhook body.
Step-by-step
- Open Settings.
Open Settings
- Go to "Integrations"
- Under "Your personal integrations", click "+Add integration".
Add Integration
- Choose Webhook V2 → click Create Webhook
Webhook V1 is an older version. Existing V1 webhooks remain active. All new webhooks use V2.
Select Webhook V2
- Fill out the Webhook form
Below is a table showing all available form fields and what each one does.
Webhook Form - all Fields Explained:
| Field | Description |
|---|---|
| Webhook Name | A freely selectable display name for the integration. Helps you identify the webhook later (e.g., “Webhook n8n – Leads”, “Zapier – Tasks”). |
| Webhook URL | The endpoint URL provided by the target system where Sally will send the webhook data. Without this URL, the webhook cannot be triggered. |
| Cookie (optional) | Optional field for systems that use session cookies instead of API tokens. Modern tools like Zapier, Make, or n8n do not require a cookie. Only used for specific internal or legacy systems. |
| Authentication Method | Defines how Sally authenticates with the target system. Possible options: • None – No Authorization header is sent; ideal for open listeners or test endpoints.• Basic Auth – Sally sends username + password as a Basic Auth header; commonly used in internal APIs. • Raw – You manually provide the full Authorization header (e.g., Bearer xyz123, ApiKey abc123).• Client Certificate (PFX + Password) – Enables mTLS authentication; only required if the target system explicitly demands a client certificate. |
| Custom Headers | Allows adding any additional headers, such as x-api-key, x-tenant-id, or signature keys. Used to secure requests or control workflows. |
| HTTP Body Version | Defines the structure of the JSON body. Recommendation: always choose the latest version to receive the most complete and up-to-date data. |
| Language | Defines the language in which content is generated. Sally uses BCP-47 based on ISO 639-1. For example, de-DE or en-US will be sent. |
| HTTP Body Customization | Defines which content Sally includes in the webhook body. Each category can be enabled or disabled individually. The following elements are available: • Tasks – All detected tasks including assignees and due dates. • Custom Insights – Results from custom insights (e.g., checklists or custom fields). • Objections – Detected objections from the conversation. • Decisions – All decisions made during the meeting. • Key Points – Important core topics or main statements of the meeting. • Meeting-type-specific elements – Content generated from the selected meeting type (e.g., question catalog). • Transcription – Full transcript sections including speakers, timecodes, and emphasis. • Summary – The generated main summary as well as HTML variants. By enabling/disabling these fields, you can precisely control how detailed the webhook body should be. |
- Click Create
Save Webhook
Your webhook now appears in the list.
Webhook is active
5. JSON Body & Field Reference
While configuring your webhook, Sally shows you a live preview of the JSON that will be sent.
You can copy the JSON directly using the built-in Copy button - useful for n8n, Make, Zapier, or testing endpoints.
JSON Body
The payload includes all detected meeting data: attendees, topics, decisions, tasks, objections, meeting-type items, and transcript parts.
Below you find:
- A complete copyable JSON example
- A full field reference table
5.1 JSON example (copyable)
{
"directoryId": "00000000-0000-0000-0000-000000000001",
"recordingSummaryId": "00000000-0000-0000-0000-000000000001",
"languageCode": "string",
"appointmentDate": "0000-01-01T00:00:00.000Z",
"appointmentSubject": "string",
"attendees": [
{
"name": "string",
"email": "string",
"invitationStatus": 0,
"attendenceStatus": 0
}
],
"meetingUrl": "string",
"meetingPlatform": "webex|msteams|zoom|googlemeet",
"summary": "string",
"combinedFullSummaryHTML": "string",
"topics": [
{
"summary": "string",
"description": "string",
"startTimeStamp": 0.0,
"endTimeStamp": 0.0
}
],
"decisions": [
{
"summary": "string",
"description": "string",
"startTimeStamp": 0.0,
"endTimeStamp": 0.0
}
],
"tasks": [
{
"subject": "string",
"description": "string",
"responsiblePersonName": "string",
"responsiblePersonEmail": "string",
"dueDate": "0000-01-01T00:00:00.000Z"
}
],
"objections": [
{
"objection": "string"
}
],
"customInsights": [
{
"id": "00000000-0000-0000-0000-000000000001",
"name": "string",
"result": "string"
}
],
"meetingTypeItems": [
{
"summary": "string",
"description": "string"
}
],
"transcriptParts": [
{
"id": "00000000-0000-0000-0000-000000000001",
"speakerName": "string",
"startTimeStamp": 0.0,
"endTimeStamp": 0.0,
"text": "string",
"emphases": "string",
"sortOrder": 0
}
]
}
5.2 Explanation of all JSON fields
| Field Name | Type | Format | Description |
|---|---|---|---|
directoryId | string (GUID) | Plain | Unique ID of your Sally organization. Used to identify which workspace the webhook originates from. |
recordingSummaryId | string (GUID) | Plain | Unique ID of the generated summary. Can be used to fetch or match data later. |
languageCode | string | Plain | Language in which the summary was generated. Sally uses BCP-47 language codes based on ISO 639-1, e.g., de-DE, en-US, fr-FR. |
appointmentDate | string (ISO date) | Plain | Date and time of the meeting or recording. |
appointmentSubject | string | Plain | Title or subject of the meeting (from the calendar or manually provided). |
attendees | Array | Plain | List of all meeting participants. |
attendees[].name | string | Plain | Name of the participant. |
attendees[].email | string | Plain | Email address of the participant. |
attendees[].invitationStatus | number | Plain | Numeric invitation status indicating how the person responded to the calendar invite. Possible values: 10 = Declined – The invitation was explicitly declined. 20 = Accepted – The invitation was confirmed. 30 = Tentatively accepted – The participant selected “Maybe”. 40 = No response – No reaction to the invitation. 50 = Organizer – The person is the meeting organizer. 100 = Unknown – Status could not be determined. |
attendees[].attendenceStatus | number | Plain | Numeric attendance status indicating whether the person actually attended the meeting. Possible values: 10 = Did not attend – The person was invited but did not join the meeting. 20 = Attended – The person was present in the meeting. 100 = Unknown – Actual attendance could not be determined. |
meetingUrl | string | Plain | Link to the online meeting (Teams, Zoom, Webex, etc.). |
meetingPlatform | string | Plain | Platform on which the meeting took place (webex, msteams, zoom, googlemeet). |
summary | string | Markdown | Compact main summary of the meeting. |
combinedFullSummaryHTML | string (HTML) | HTML | Full formatted summary in HTML – ideal for CRMs, ticketing systems, or emails. |
topics | Array | Plain | Topics/sections detected in the conversation. |
topics[].summary | string | Markdown | Short description of the topic. |
topics[].description | string | Markdown | More detailed description of the conversation section. |
topics[].startTimeStamp | number (decimal) | Plain | Start time of the topic in seconds (relative to the recording). |
topics[].endTimeStamp | number (decimal) | Plain | End time of the topic in seconds. |
decisions | Array | Plain | All decisions made in the meeting. |
decisions[].summary | string | Markdown | Short description of the decision. |
decisions[].description | string | Markdown | Detailed description of the decision. |
decisions[].startTimeStamp | number (decimal) | Plain | Timestamp when the decision was mentioned. |
decisions[].endTimeStamp | number (decimal) | Plain | Timestamp when the decision topic ended. |
tasks | Array | Plain | Tasks/action items detected by Sally. |
tasks[].subject | string | Markdown | Title of the task. |
tasks[].description | string | Markdown | Description or context of the task. |
tasks[].responsiblePersonName | string | Plain | Person responsible for the task. |
tasks[].responsiblePersonEmail | string | Plain | Email of the responsible person. |
tasks[].dueDate | string (ISO date) | Plain | Due date of the task in ISO 8601 format. Only set if Sally detects a date in the conversation. Example: 2025-03-15T00:00:00.000Z. |
objections | Array | Plain | Objections or concerns mentioned during the meeting. |
objections[].objection | string | Markdown | The formulated objection. |
customInsights | Array | Plain | Results of your custom insights/prompts. |
customInsights[].id | string (GUID) | Plain | Unique ID of the custom insight field. |
customInsights[].name | string | Plain | Name of the insight field. |
customInsights[].result | string | HTML | Result generated by the prompt. |
meetingTypeItems | Array | Plain | Content generated by your selected meeting type (e.g., questions, sections, checks). |
meetingTypeItems[].summary | string | HTML | Short description of the item. |
meetingTypeItems[].description | string | HTML | Detailed description of the meeting-type element. |
transcriptParts | Array | Plain | Each recognized transcript segment – structured by speaker and time. |
transcriptParts[].id | string (GUID) | Plain | Unique ID of the transcript segment. |
transcriptParts[].speakerName | string | Plain | Name of the speaker. |
transcriptParts[].startTimeStamp | number (decimal) | Plain | Start time of the segment in seconds. |
transcriptParts[].endTimeStamp | number (decimal) | Plain | End time of the segment in seconds. |
transcriptParts[].text | string | Plain | Spoken content. |
transcriptParts[].emphases | string | Plain | List of detected emphasized words within the segment. This field contains an array of objects, each containing the emphasized word and its start and end timestamps. If no emphasis is detected, the array is empty. Example: [{"word":"Yes","startTime":104.89,"endTime":104.89},{"word":"next","startTime":105.09,"endTime":105.09},{"word":"page.","startTime":105.41,"endTime":105.41}] |
transcriptParts[].sortOrder | number (int) | Plain | Sequential number indicating the order of the segment in the full transcript. Values are ascending: lower numbers represent earlier speech, higher numbers later speech. |
6. Test the connection & view logs
6.1 What the logs are for (and why they matter)
The logs show you what Sally sent and when, and how the target system responded.
They help you with:
- Verifying that events were sent correctly
- Troubleshooting incorrect URLs or missing permissions
- Inspecting the content (payload)
- Measuring performance (e.g., response times)
- Ensuring traceability for audits
6.2 How to find your webhook logs
- Go to Integrations.
- Open your webhook.
- Click Logs.
Open Logs
You’ll see a list of all webhook attempts:
Webhook events
6.3 How to read a log entry
An entry contains for example:
- Execution time
- Target endpoint (URL)
- HTTP status (e.g.,
202 Accepted= successful) - Latency/Duration
- Event (which Sally event triggered the webhook)
- Retries (in case of failures)
- Details about request & response
- 2xx Success → Target accepted the request
- 4xx Client error → Usually a configuration issue (e.g.,
401 Unauthorized) - 5xx Server error → Target system unavailable; Sally will retry
6.4 Common issues & quick fixes
- Incorrect URL → Compare with your target workflow
- Missing authentication → Check tokens or headers
- Payload mismatch → Try a newer version
- Rate-limiting (429) → Reduce request frequency
- Target system down (5xx) → Check system availability
7. FAQ & Troubleshooting
My webhook isn't sending anything.
- Check whether the triggering event actually occurred
- Ensure the webhook is active
- Review the logs
Where do I get the webhook URL?
- Always from the target system (Zapier, Make, etc.)
Which version should I choose?
- Always Version 3 (Latest) unless using a legacy workflow
How long are logs stored?
- Logs are stored for 90 days and then deleted automatically.







