Skip to main content
Connect a public HTTPS receiver under Settings → Integrations → Webhooks. When a selected monitor flags a new call, Zelto sends a monitor.matched event. Your receiver can save the result in your database, CRM, or customer timeline. Zelto sends the event to your HTTP endpoint; your system controls the database write.

Set up a destination

Owners and administrators can manage destinations and delivery history.
  1. Create the monitors whose positive results you want to receive.
  2. Choose Add destination, enter a name and a public HTTPS URL on port 443, and select at least one monitor (up to 100). Select current monitors (up to 100) selects up to 100 from the current list; future monitors are not subscribed automatically.
  3. Save the destination. It starts Paused. Copy the generated signing secret, which is displayed only once, and store it securely in your receiver.
  4. Choose Send test. Handle webhook.test as described below and acknowledge it with any 2xx response. Tests can run while the destination is paused.
  5. Choose Enable deliveries in the destination’s setup steps, or enable deliveries from Edit destination. Only calls ingested after activation are eligible. Check Last test and the history to confirm delivery; background scheduling normally picks up pending events within one minute.
Existing calls are not exported on activation. Adding another monitor preserves coverage for unchanged subscriptions. Removing and later re-adding a monitor, or pausing and reactivating the destination, starts coverage from the new activation time. A provider’s original call start time can precede ingestion. Destinations show only the receiver hostname; credentials, paths and query parameters stay hidden. When editing, leave the URL blank to keep it. Generate a new signing secret rotates the secret and pauses the destination. Update your receiver, send a test, and enable deliveries again. Changing the URL or secret cancels pending deliveries; set up your receiver before enabling delivery. An HTTP request already started may still arrive after a destination is paused or edited.

Events

monitor.matched

One event is recorded for the first positive result of each call and monitor while an eligible destination exists. Reprocessing or changing the monitor’s version does not create another event for that pair. A previously negative result can produce its first event when it becomes positive. Negative, unscored, failed, preview, benchmark, and isolated experiment results do not emit events. A later correction does not retract an already delivered detection. This is a post-analysis event, not live keyword detection during a call. It contains the monitor’s existing typed outputs and explanations. A list of matched keywords is available only if your monitor actually extracts that list. Synthetic example:
Use data.conversation.externalId, the call ID you originally supplied, to join the event to your call records. endUserId is an optional opaque person ID you can supply when uploading calls. Either may be null when absent. company_id identifies a company or creditor and must not be treated as the called person’s ID. occurredAt is when the event was recorded; evaluatedAt identifies the captured result. startedAt may be null. overallScore is a number or null; items[].value preserves its original JSON type. The snapshot stays unchanged across retries. Full transcripts, recordings, phone numbers, prompts, and free-form call metadata are not included. Monitor outputs can themselves contain customer information, so store them with the same controls as your call results. Filter-only monitors can have an empty items list: passing their filters is itself the positive result. No extra keyword extraction is performed.

webhook.test

Tests contain no real call or customer data:
Verify the signature and return 2xx for this type. Do not insert a customer history entry. Tests are explicitly requested from the destination screen, appear separately by event type in history, and do not reserve a monitor match.

Verify the signature

Every request contains: The signed message is timestamp + "." + rawBody. Verify the original raw request body, before parsing JSON or changing whitespace. The timestamp and signature change for each attempt; the body and event ID remain the same. This Node.js verifier rejects signatures older than five minutes:
Read the header values from your HTTP framework and pass the raw UTF-8 body, then parse JSON only after verification. Reject failed verification with a non-2xx response. Keep the signing secret server-side.

Save once, acknowledge, and retry

After verification, branch on type. For monitor.matched, identify the person through your call’s external ID or supplied endUserId, then commit the event ID and the history entry in one database transaction. Enforce a unique constraint on the event ID. Return 2xx only after durable processing, or after durably queuing the work in your system. If the ID was already processed, return 2xx without inserting another history entry. Delivery is at least once, with no ordering guarantee. A response can be lost after your database commit, so automatic and manual retries may repeat an event. Do not deduplicate by monitor name or assume only one monitor can match a call. Zelto allows up to six automatic attempts. Base delays between attempts are 5, 10, 20, 40, and 80 minutes, plus up to 30 seconds of jitter. Non-2xx responses, network failures, and timeouts are retried; a valid Retry-After on 429 or 503 postpones the next attempt if later. Invalid or private destinations fail without repeated delivery attempts. DNS has a 5-second timeout and HTTP has a 15-second timeout. Redirects are not followed. The scheduler can add a short delay to a due attempt. Deliveries run separately from call analysis. Delivery history shows the latest 50 deliveries, statuses, attempts, bounded error summaries, and up to 100 recent attempt outcomes. Monitor detections show the monitor and a link to the retained call, including its external reference when present. Search and status filters apply to these latest 50 deliveries. Technical event IDs and attempt logs are available under Technical details and attempts. Pending deliveries refresh every 15 seconds while the page is visible; automatic updates pause while editing or viewing a one-time secret. Use Update to refresh manually. Use Resend for a terminal delivery while its content is retained and the destination is enabled (test events can also be resent while paused). Resend uses the current destination configuration, the same event ID and body, and a new automatic-attempt budget. An active or still-leased delivery cannot be restarted; wait for it to finish or its lease to expire. There is no bulk replay of historical calls. Event content is retained for at most 30 days from call ingestion, or the organization’s shorter effective retention policy. Deleting the call, monitor, or organization removes the related event content. Expired content cannot be sent again. A minimal event identifier remains while the call and monitor exist to prevent re-emitting the same first match after content cleanup.

Other webhook features

These per-call webhooks are separate from the aggregate weekly monitor report webhook, whose monitor_report.weekly payload and delivery-ID deduplication are unchanged. Provider webhooks in voice integrations send calls into Zelto; this integration sends detections out to your system.