Apart from retrieving analysis results through the API, Voicesense also provides users with the possibility to configure webhooks which will send the file scores though http to the configured endpoint on the client side.
For testing purposes there is a site https://webhook.site which can be used as a fake webhook listener.
To configure the webhook, please follow these steps:
1. Login to the https://score.voicesense.com as a Company Operator
2. Go to Company Operator -> Webhooks

3. In the upper right corner click Create

4. Fill in the Delivery URL field with url which should be notified on audio analysis finish and click Save.

All audio scores notifications will be sent to the configured endpoint.
You can add headers and customize the body template if needed.
You can also change the Request Type to one of the available options: POST or PUT.
Example Message
{
"StreamId": "3a0440bf-7220-4a42-9245-7e7ea4bf6560",
"ReferenceId": "7c2eef00-3134-40ed-a779-8a34c9048ba8",
"PredictorState": 0,
"AudioDuration": 305.57,
"ScoreLeft": {
"Scores": null,
"TalkDuration": 0
},
"ScoreRight": {
"Scores": {
"Engaged": 5,
"Attentive": 4,
"Open": 4,
"WBEnergy": 4,
"WBEmotion": 4,
"WBSocial": 2,
"OverallWellBeing": 4,
"WBCoping": 4,
"WBStressControl": 4,
"EnergyLevel": 10,
"Attrition": 3,
"Burnout": 2,
"Satisfaction": 1,
"Depression": 1,
"AttitudeLevel": 2
},
"TalkDuration": 208
},
"ErrorMessage": null
}
___________________________________________________________________________________________________________________________________________________________________________________________________________
Customized Body Template
If you customize the Webhook Body Template, i.e. by providing the following content into the Body Template field:
{
"AudioReferenceId": "{{ReferenceId}}",
"VoicesenseId": "{{StreamId}}",
"Score": "{{ScoreRight.Scores.Engaged}}",
"Error": "{{ErrorMessage}}"
}

only provided values will be received in the Webhook output:
{
"AudioReferenceId": "8c31983f-5cbc-4169-81ac-a4f238f10e47",
"VoicesenseId": "ae5be27e-b67d-4d89-aa0b-33eedea470f3",
"Score": "2",
"Error": "null"
}
Valid variable paths are:
PredictorState
AudioDuration
StreamId
ReferenceId
EngineVersion
CompanyId
ErrorMessage
ScoreLeft
andScoreRight
ScoreLeft.TalkDuration
andScoreRight.TalkDuration
ScoreLeft.Scores
andScoreRight.Scores
ScoreLeft.Scores.{ScoreName}
andScoreRight.Scores.{ScoreName}
, whereScoreName
is any name (no validation), e.g.Engaged
___________________________________________________________________________________________________________________________________________________________________________________________________________
Verifying requests
When Voicesense sends you a webhook message, it adds a special “X-Voicesense-Signature” HTTP request header. This signature is created by hashing a raw request body ({“StreamId”: …}), and combining it with an HMAC signing secret. The resulting value is unique for each request, and can be used to verify if the request is coming from the Voicesense, and to guarantee that it was not modified by any third party.
Follow this procedure to validate the signature:
1. Get a signing secret assigned to your company from the Webhooks management page, and store it so that your app can use it.

2. Get the raw request body from the incoming webhook request. This must be an unformatted and unmodified body, just as it was sent in the HTTP request.
3. Get the signature value from “X-Voicesense-Signature” header.
4. Hash the request body, using the signing secret as a key.
5. Calculate the hex digest of the hash and compare it with the signature.
Code example
The following script shows how to validate the signature using Python.
You’ll need to implement the same logic in the programming language of your choice.
import hashlib
import hmac
secret = bytes('qn38UciAEBTR1vlWPyPR205U438I6PAS', 'utf-8') # replace with your webhook signing secret
body = bytes('''{"test":"body"}''', 'utf-8') # replace with webhook request body
signature = 'a30d5e4941a55d747bbaf39efb54ed5d1784cbd373686fe9e24375071bc0d73f' # replace with signature from the header
hmac_hash = hmac.new(secret, body, hashlib.sha256)
signature_valid = hmac.compare_digest(hmac_hash.hexdigest(), signature)
print(signature_valid)
Notice that the calculated hash and signature are compared using a “compare_digest” method, instead of comparing the values directly. This is an extra security measure against the timing attacks.
Secret regeneration
Use the “Regenerate” button to generate a new secret, and replace the old one with it. You can use that feature if you plan to rotate the secret, or your old secret got compromised.