API - VoIP Webhook
Public route used by external telephony providers/centrals to send already completed calls to SprintHub.
For each received event, SprintHub:
identifies the lead by phone (or creates a new lead, if the number is unknown);
logs the call in the call history (
voip_history), visible in the CRM;logs the event in the lead timeline (
voip.call_incomingorvoip.call_outgoing).

Endpoint
Replace CLIENT_NAME with the instance name (e.g.: myclient). The parameter ?i= is what identifies the client's database and must always be present in the URL configured in the provider.
Authentication
Authentication is optional and defined per instance:
Client without secret configured
The endpoint accepts the request without additional validation
Client with secret configured
It is mandatory to send the secret, otherwise the response is 401 unauthorized
When the secret is active, send it in one of two ways:
or
The secret configuration (
voip_webhook_secret) is done by the SprintHub team in the client's instance.
Request body
The body is an envelope with two fields: event and data.
event
string
yes
Only value accepted today: "call"
data
object
yes
Completed call data (table below)
Fields of data
user
number
yes
SprintHub user ID who made/received the call. Must exist in the instance
leadPhone
string
yes
Contact phone number, with country code. Non-numeric characters are removed
type
string
yes
INCOMING (received) or OUTGOING (made)
status
string
yes
COMPLETE (answered) or INCOMPLETE (not answered)
duration
number
yes
Duration in seconds. Use 0 for unanswered calls
record
boolean
yes
Indicates whether the call was recorded in the central
service
string
yes
Provider/central identifier (up to 32 characters). E.g.: "twilio"
lead
number
no
Lead ID, if already known. If omitted, the lead is resolved by phone
leadName
string
no
Contact name (up to 64 characters)
userName
string
no
Operator name (up to 64 characters)
callId
string
no
Call ID in the provider (up to 64 characters). Used for reconciliation
description
string
no
Free-form note about the call (up to 1000 characters)
Fields not listed above are rejected: any extra property results in
400 invalid_body.
Example — received and answered call
Example — made and unanswered call
Example with cURL
Postman Collection
File: voip_webhook_postman_collection.json — import into Postman at Import > File.
Before running, adjust the collection variables:
baseUrl
API URL (e.g.: https://api.sprinthub.app)
instance
Instance name, used in the ?i=
secret
Webhook secret. Leave empty if the instance does not use a secret
userId
ID of an existing user in the instance
leadPhone
Phone number used in tests
service
Provider identifier sent in service
leadId
Fill in only for the request "with lead provided"
The collection has two folders:
Success — answered incoming call, unanswered outgoing call, minimal payload, with lead provided and with masked phone number. Each request validates
201/msg: createdand stores the returned ID in the variablehistoryId.Errors — the cases of
400(missing required field,eventinvalid, invalid enum, extra field) and the401invalid secret.
Requests in the folder Success create real records in the call history and may create the lead from the provided phone number. Use a test instance. The
callIdis generated with{{$timestamp}}so each submission is unique.
What SprintHub does with the event
Validates the body — format, types and required fields.
Normalizes the phone number — removes everything that is not a digit from
leadPhone.Resolves the lead:
if
leadwas sent, it is used directly;otherwise, it looks for an existing lead by the phone, mobile and WhatsApp fields (with handling of the 9th digit in Brazilian numbers);
if it does not find one, it creates a new lead with source VoIP, using the WhatsApp name and photo when the number has an active account, or the phone number itself as the name.
Registers the call in the call history and returns the generated ID.
Registers in the lead timeline the event
voip.call_incomingorvoip.call_outgoing, with operator, phone, status, duration,callIdandservice.
If lead resolution/creation fails, the call is still recorded — just without a lead link (and, in that case, without a timeline event).
Responses
201
{ "msg": "created", "id": 123 }
Call recorded. id is the identifier in the call history
400
{ "msg": "invalid_body", "err": { ... } }
Invalid body: missing required field, wrong type or extra field
401
{ "msg": "unauthorized" }
Secret configured in the instance and not sent (or sent incorrectly)
500
{ "msg": "failed_voip_webhook", "err": "..." }
Failed to save the call. It can be resent
The field err of the 400 brings the validation detail, useful for debugging the integration:
Best practices
Send one event per completed call, after the end — the webhook does not handle progress events (ringing, answered, etc.).
There is no deduplication by
callId: resending the same event creates a new record in the history. Always sendcallIdto allow reconciliation and avoid unnecessary resends.Resend only on error
500or timeout, with progressive wait between attempts. Since the failure may occur after the call has been recorded, a resend can generate a duplicate record — use thecallIdto identify.durationin seconds, always an integer.record: trueonly indicates that there is a recording in the central; the audio is not sent or attached by this endpoint.Respect text field size limits (
userName,leadNameandcallIdup to 64;serviceup to 32;descriptionup to 1000). Larger values may be truncated or cause an error500.Automation: the trigger "received call" (
leadPhoneCall, eventreceived) recognizes the callsINCOMINGreceived by this webhook. The filter by operator number does not apply, since the webhook does not send that number.This endpoint does not generate credit usage or automatic transcription — it only records the call history and the event on the lead.
Last updated
Was this helpful?