Skip to main content

Webhooks and call events

Polling GET /api/v1/calls/{id}/status is the simplest way to get a result. When you need lower latency or fewer requests, Speechlytics can push call updates to you over two channels:

ChannelHow it worksBest for
Account webhookSpeechlytics POSTs each call update to a URL you provide.Server-side integrations that can expose an HTTPS endpoint.
Call-events WebSocketYour client holds a socket open and receives the same updates as text frames.Services that cannot accept inbound HTTP.

Both channels carry the same payload. For live-call intelligence (keywords, alerts, sentiment, coaching), use the live events stream instead.

Account webhook​

Setting it up​

The webhook is configured on your account by Speechlytics. Provide:

  • the HTTPS URL to receive events;
  • optionally, a username and password. When both are set, every request carries Authorization: Basic <base64(username:password)>. Verify it on your side.

The request​

POST /your/webhook HTTP/1.1
Content-Type: application/json
Authorization: Basic ZXhhbXBsZTpzZWNyZXQ=

{ "Id": 12345, "Status": 2, "StatusDescription": "Processed", ... }

The body is the call's status object, the same model returned by GET /api/v1/calls/{id}/status, with these differences:

  • Property names are PascalCase (Id, Status, Transcription.LeftChannel, CallAnalysis.ConversationSummary) rather than the camelCase used by REST responses. Configure your deserializer to be case-insensitive.
  • Inside CallAnalysis, section names are the compact property names (CallMetadata, ConversationSummary, CustomerSignals, ScoringInsights) rather than the spaced labels used by the REST response ("Call Metadata").
  • Enums are integers.

When it fires​

A webhook is sent each time a call reaches a notable stage, so one call can produce more than one webhook, for example once after keyword matching and again after the summary. Use Status to decide what to do:

  • 2 (Processed): a complete result. Transcript, keywords, analytics and custom questions are committed.
  • Any other value: progress information. You may ignore it.

A call that was already delivered as Processed can be delivered again later with different keywords, scores or summary, for example after its transcript is polished or reverted. Upsert on Id rather than inserting.

For live calls on accounts with polishing enabled, the keyword and summary webhooks arrive after the automatic polish finishes.

Delivery guarantees​

  • Delivery is best-effort. A request that fails or returns a non-2xx status is not retried.
  • Respond quickly with 2xx and do the heavy work asynchronously.
  • Make your handler idempotent on Id, because the same call can be delivered more than once.
  • For critical workflows, reconcile periodically with GET /api/v1/calls over a recent date range to catch anything missed.

Encrypted webhooks​

When response encryption is on for the account, the body is an encryption envelope and the request carries:

X-Speechlytics-Encryption: true
X-Speechlytics-Key-Id: 3f9a2c1b

These headers are omitted when the event was sent in the clear. If an event cannot be sealed it is still delivered, unencrypted and without the headers, rather than dropped. Always handle both cases.

Call-events WebSocket​

Connect with the JWT in the query string:

wss://api.example.com/api/v1/calls/events?token=<jwt>
  • Each text frame is one call update with the same payload as the webhook.
  • One socket per account is registered at a time. A second concurrent connection for the same account does not receive events, so run a single consumer and fan out internally.
  • Reconnect with backoff when the socket closes, then reconcile with GET /api/v1/calls for the period you were disconnected. The socket does not replay missed events.
  • When encryption is on, every frame is an envelope. There are no headers on a frame: decrypt unconditionally, and treat a frame that is not an envelope as plaintext.

Choosing a channel​

NeedRecommendation
Simplest integrationPoll GET /api/v1/calls/{id}/status until status is 2, 3 or 4.
Server with a public HTTPS endpointAccount webhook, plus a periodic reconciliation job.
No inbound connectivityCall-events WebSocket.
Results in a CRMA HubSpot integration writes calls to HubSpot for you.