POST request in response to certain events occurring in your workspace.
See support Events below.
Configuring Webhooks
Webhooks depend on you providing a URL endpoint to a secured HTTPS server that can receive & respond to delivered messages from Quarterzip. Testing can performed with online services such as webhook.site, or against locally running servers using ngrok or Cloudflare tunnels.- In the Quarterzip dashboard, go to Settings → Webhooks.
- Enter the HTTPS URL that should receive events.
- Choose which events to send to this endpoint. At least one is required.
- Toggle Enabled on and save.
Ad-hoc subscriptions
When you launch a call through the SDK, you can also send that call’s events to extra URLs on top of your registered endpoints:Secured with Signatures
Quarterzip signs every delivery using the open Standard Webhooks specification. This includes awebhook-signature header value that you can verify against to ensure that the webhook message was delivered by Quarterzip and was not tampered in transit.
Verifying the signature is optional. Webhook message are not encoded.
Verifying the signature
Each workspace has one signing secret, shown on Settings → Webhooks, which signs deliveries to every endpoint. Each request includes three headers:| Header | Description |
|---|---|
webhook-id | Unique ID for this delivery (for example, call_completed_v1_abc123). |
webhook-timestamp | Send time as a Unix timestamp (seconds). |
webhook-signature | Space-separated list of v1,<base64-signature> values. |
standardwebhooks libraries can be used to verify a webhook delivery with only a few lines of code.
Rotating the secret
A new signing secret can be generated from Settings → Webhooks. Rotation takes effect immediately. Deliveries signed with the old secret will fail verification until you update your consumer.Delivery, Retries & Timeouts
Return any2xx status code to acknowledge a webhook. Anything else 4xx, 5xx, a connection error, or a timeout) is treated as a failed delivery and will be retried. Redirects are not followed, so a 3xx also counts as a failure.
As guidance: it is best to acknowledge first and then process later. Your endpoint should do the minimum needed to persist the event and return 2xx immediately. Doing the work inline risks hitting the timeout, and a timeout means redelivering an event you have already processed.
Each delivery attempt is given 30 seconds. An attempt that hasn’t completed in that window is abandoned and retried. A failed delivery is retried up to 7 times with exponential backoff with jitter, starting with a 15 second delay. After the final retry the event is dropped and that endpoint is automatically disabled. Other endpoints in the workspace are unaffected, and an endpoint is never disabled for failures on Quarterzip’s side.
Retries reuse the same webhook-id header as the original attempt. You should expect duplicates even when nothing looks wrong. A response we never received (because it arrived after the timeout, or the connection dropped mid-response) is indistinguishable from a failure, so we may retry an event your endpoint already processed successfully.
Payloads larger than 5 MB are not sent and are not retried. It is very unlikely that any payload will reach this threshold, but may occur for a call with an extremely long transcript.
Delivery, Retries & Timeouts
Return any2xx status code to acknowledge a webhook. Anything else — 4xx, 5xx, a connection error, or a timeout — is treated as a failed delivery and will be retried.
Acknowledge first, process later. Your endpoint should do the minimum needed to persist the event (write it to a queue or a table) and return 2xx immediately. Doing the work inline risks hitting the timeout, and a timeout means redelivering an event you have already processed.
Each delivery attempt is given 30 seconds. An attempt that hasn’t completed in that window is abandoned and retried. A failed delivery is retried up to 7 times with exponential backoff with jitter, starting with a 15 second delay. After the final retry the event is dropped and the endpoint is considered unreachable - this will automatically disable the workspace’s webhooks.
Retries reuse the same webhook-id header as the original attempt. You should expect duplicates even when nothing looks wrong. A response we never received — because it arrived after the timeout, or the connection dropped mid-response — is indistinguishable from a failure, so we may retry an event your endpoint already processed successfully.
Best Practices
- While webhooks is in preview, ensure that your server’s endpoint handler responds with a
2xxstatus code. Consider wrapping the handler in atry...except,try...catch, or equivalent. Failing to do so risks the workspace’s registered webhook to be automatically deactivated; see Delivery, Retries & Timeouts. - Evaluate received messages by event
type. The likelihood of new event types encourages the following pattern:
Events
call.completed.v1
Quarterzip sends this event after a call finishes processing. The request is a JSON POST with Content-Type: application/json.
Example payload
call.recording.ready.v1
Quarterzip sends an event after a call’s recording is ready for download. The delivery of this event is not guaranteed; calls may not have recordings, or workspaces may have recordings disabled.
Example Payload
call.rating.submitted.v1
Quarterzip sends an event after a caller submits a star rating for a call, and again if they change it. Ratings are optional and a caller may give one well after the call has ended, so this event is independent of call.completed and can arrive before or after it. Rating is an integer from 1 to 5.
Changing a rating produces a second delivery with its own webhook-id, so a correction is not a duplicate and will not be filtered out by idempotency checks. Deliveries for the same call are not guaranteed to arrive in order, so compare the envelope timestamp and ignore any rating older than one you have already applied.
Example Payload
call.interpretation.ready.v1
Quarterzip sends this event once it has finished analysing a completed call. It summarises how the call went and lists each goal the user raised, along with how it came up, how it ended, and whether anything blocked it.
Defining a successful call is hard. At Quarterzip, we’ve formed strong opinions on how to evaluate a call with an agent. These definitions and terms, while they might make sense to you, may not be clear to an LLM tool ingesting this data. Below is a prompt of definitions to best help LLM tools to understand the data Quarterzip produces, so that an LLM can better answer your questions.
LLM definitions for call interpretations
Concepts
Every goal a user raises on a call is tagged with a type, an origin, and an outcome. Users can discuss several goals in one call, and each goal is assessed on its own. Three of the outcomes combine into the enablement rate.Goal type
The type describes what the user is trying to do.| Type | Description |
|---|---|
| Task | The user is trying to accomplish an action in your product. |
| Question | The user has a question about something inside your product. |
| Problem | Something in your product is behaving unexpectedly and needs explaining or repairing. |
Goal origin
The origin describes how the goal came up during the call.| Origin | Description |
|---|---|
| User raised | The user brought it up themselves, unprompted. |
| Agent offered | The agent proposed it without any specific cue. |
| Agent noticed | The agent saw something on the user’s screen, such as a failing diagnostic, an error, or a half-finished form, and proposed acting on it. |
| Resumed | The goal was carried over from an earlier call, or from earlier in the same call. |
Goal outcome
The outcome is Quarterzip’s determination of how the goal ended.| Outcome | Description | Counts as enabled |
|---|---|---|
| Confirmed resolved | Using screen awareness, Quarterzip confirmed the goal was achieved. | Yes |
| Assisted | The agent helped the user, but Quarterzip could not confirm the goal was resolved. For example, the user was cut off mid-sentence or screen sharing dropped. | Yes |
| Deferred | The user chose to stop before the agent could resolve the goal, without facing a blocker. For example, the user moved on, ran out of time, or said they’d carry on alone. | Yes |
| Blocked | The user could not achieve the goal because something was preventing them, such as a product bug or gap, an external dependency, or a gap in the agent’s knowledge. | No |
| Unclear | There was no signal from the user about whether the goal was achieved. | No |
Enablement rate
A user is considered enabled when their goal’s outcome is confirmed resolved, assisted, or deferred. The enablement rate is comparable to the assumed resolution rate reported by tools such as Intercom or Sierra. When working with webhooks, construct the enablement rate by summing the three rates:Viewing outcomes in Quarterzip
| Where | What you can do |
|---|---|
| Call insights dashboard | Track your agents live: engaged calls, unique users, engaged hours, enablement rate, CSAT, outcomes by agent, and the reasons goals were blocked. |
| Call log | Review individual calls. Each call lists the user’s goals with their type, origin, and outcome, plus a description of what happened, the steps the agent took the user through, and direct quotes from the user. |
Example Payload
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Not receiving any events | Endpoint is not Enabled, isn’t subscribed to the event, or no subscribed events have occurred yet. Check the Delivery log. |
| Endpoint was disabled on its own | A delivery failed every retry. Fix the endpoint, then turn Enabled back on. |
| Signature verification fails | Verifying against a re-serialized body instead of the raw bytes, or using an old secret after a rotation. |
| Can’t save the URL | URL must be https, use a full domain name (not localhost or a bare hostname), and must not include a username or password. |
| Deliveries fail with “This destination is not allowed” | The URL resolves to a private or internal address. These are refused at delivery time and are not retried. |

