Webhooks
Receive notifications on time using webhooks.
Webhooks are used to notify you about the changes in verification statuses.
The following types of webhooks are available:
Mind the following:
- We do not send any information to endpoints using HTTP, only HTTPS.
- Not receiving an answer from a webhook endpoint for more than 5 seconds is considered to be a timeout, and our service will try to resend the same webhook later.
- Supported versions of TLS protocol are 1.2 or higher.
- When a webhook HTTP request fails, we attempt to resend it four times: after 5 minutes, 1 hour, 5 and 18 hours until request succeeds. We also send an email notification informing you about the failed webhook event.
- Check the
createdAtMs
field of the webhook payload to make sure that you are getting the relevant applicant status.
Create webhooks
To create a webhook:
- in the Dashboard, go to the Webhooks page and click Create webhook.
- Provide a preferable webhook name.
- Select a webhook receiver type, which can be any HTTP address, Slack, Telegram, or email.
- Specify the target endpoint where webhooks are expected to be received. Depending on the selected receiver type, you can specify an HTTP address, Slack webhook URL, Telegram API token with Telegram chat ID after
@
, or email. - Select a webhook type. For more information, see user verification webhooks and transaction monitoring webhooks.
- Select an applicant type for which to send the webhook.
- Specify a secret key to be used to calculate the digest with the HMAC algorithm.
- Select a signature algorithm to be used when verifying the webhook sender.
- Add custom headers if necessary. Available only if
HTTP address
is set as the webhook receiver type. - [Optionally] Select a source key. Available only if at least one source key is configured in your environment.
- Enable the Resend failed webhooks several times toggle to enable/disable sending failed webhooks repeatedly.
- Click Test webhook to see how it performs.
- Save your changes.
Verify webhook sender
To make sure the webhook is sent by Sumsub, we sign it with the HMAC algorithm.
Important
To use this feature, set a Secret Key value when creating a webhook.
We also send the additional X-Payload-Digest-Alg
header that specifies one of the following algorithms to be used:
HMAC_SHA1_HEX
(legacy, deprecated)HMAC_SHA256_HEX
(default upon creating a new webhook)HMAC_SHA512_HEX
You can choose among these algorithms when setting up your webhooks.
To verify the webhook sender:
- Get a webhook
x-payload-digest
header value and payload as it is, without any alteration or converting to JSON. - Receive the HTTP webhook body in bytes.
- Calculate the digest with the raw webhook payload in bytes and the HMAC algorithm specified in the
x-payload-digest-alg
header. - Compare the
x-payload-digest
header value with the calculated digest.
Note
- Do not rely on our IP addresses for whitelisting them as the webhook sender because they can change.
- Make sure to test your webhooks before sending its URL to us. At a minimum, it should not give a 500 HTTP response or require any sort of authorization.
To check that you compute the digest the same way we do, use the following POST
method:
curl -X POST \
'https://api.sumsub.com/resources/inspectionCallbacks/testDigest?secretKey=SoMe_SeCrEt_KeY&digestAlg=HMAC_SHA1_HEX' \
-H 'Content-Type: text/plain' \
-d 'someText'
Name | Type | Required | Description | Default |
---|---|---|---|---|
# {body} | Object | Yes | Any payload. | N/A |
secretKey | String | Yes | A secret key that can be used for signing. | N/A |
digestAlg | String | No | A signature algorithm that can be used for signing. Possible values: HMAC_SHA1_HEX , HMAC_SHA256_HEX , HMAC_SHA512_HEX . | HMAC_SHA1_HEX |
Response
{
"digest": "f6e92ffe371718694d46e28436f76589312df8db",
"digestAlg": "HMAC_SHA1_HEX"
}
Example request to the client endpoint
curl -X POST \
'https://callbackurl.com/kyc' \
-H 'Content-Type: application/json' \
-d '{
"applicantId": "5cb56e8e0a975a35f333cb83",
"inspectionId": "5cb56e8e0a975a35f333cb84",
"correlationId": "req-ec508a2a-fa33-4dd2-b93d-fcade2967e03",
"externalUserId": "12672",
"type": "applicantReviewed",
"reviewResult": {
"reviewAnswer": "GREEN"
},
"reviewStatus": "completed",
"createdAtMs": "2020-02-21 13:23:19.111",
"clientId": "SumsubClient"
}'
Example of computing the digest
export function checkDigest(req): boolean {
const algo = {
'HMAC_SHA1_HEX': 'sha1',
'HMAC_SHA256_HEX': 'sha256',
'HMAC_SHA512_HEX': 'sha512',
}[req.headers['X-Payload-Digest-Alg']]
if (!algo) {
throw new Error('Unsupported algorithm')
}
const calculatedDigest = crypto
.createHmac(algo, SUMSUB_PRIVATE_KEY)
.update(req.rawBody)
.digest('hex')
return calculatedDigest === req.headers['x-payload-digest']
}
private async Task<bool> CheckDigest(HttpRequest request)
{
using (var reader = new StreamReader(request.Body))
{
var body = await reader.ReadToEndAsync();
byte[] byteArray = Encoding.UTF8.GetBytes(body);
using (MemoryStream stream = new MemoryStream(byteArray))
{
string algo = request.Headers["x-payload-digest-alg"];
string calculateDigest = string.Empty;
switch (algo)
{
case "HMAC_SHA1_HEX":
using (var hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(_verificationAccessor.SumSubPrivateKey)))
{
calculateDigest = hmacsha1.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e));
}
break;
case "HMAC_SHA256_HEX":
using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(_verificationAccessor.SumSubPrivateKey)))
{
calculateDigest = hmacsha256.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e));
}
break;
case "HMAC_SHA512_HEX":
using (var hmacsha512 = new HMACSHA512(Encoding.UTF8.GetBytes(_verificationAccessor.SumSubPrivateKey)))
{
calculateDigest = hmacsha512.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e));
}
break;
default:
using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(_verificationAccessor.SumSubPrivateKey)))
{
calculateDigest = hmacsha256.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e));
}
break;
}
return calculateDigest == request.Headers["x-payload-digest"];
}
}
}
<?php
$return = file_get_contents('php://input');
$algoStr = $_SERVER['HTTP_X_PAYLOAD_DIGEST_ALG'];
$digest = $_SERVER['HTTP_X_PAYLOAD_DIGEST'];
$algo = match($algoStr) {
'HMAC_SHA1_HEX' => 'sha1',
'HMAC_SHA256_HEX' => 'sha256',
'HMAC_SHA512_HEX' => 'sha512',
default => throw new \RuntimeException('Unsupported algorithm'),
};
$res = $digest === hash_hmac(
$algo,
$return,
'secret'
);
echo $res ? "true" : "false";
?>
Get webhooks with Telegram
To receive webhooks in Telegram:
- Create a Telegram bot with BotFather.
- Save the bot token.
- Create a new group and invite the bot to this group.
- Get the list of updates for your bot using:
https://api.telegram.org/bot<YourBOTToken>/getUpdates
. - Paste the bot token and
chatId
into the Target field of the webhook configuration and save it.
Note
The bot token and
chatId
should be pasted with@
between them in the following format:telegram_bot_token@chatId
Manage webhook settings
You can manage your webhooks settings in any of the following ways:
- Edit webhook parameters. Lets you edit webhook parameters at any time if you need to change some of the existing webhook settings.
- Remove webhooks. Lets you remove a webhook configuration at any time in case you no longer need it.
- Disable webhooks. Lets you disable the webhook. You can reenable it at any time.
Updated 9 days ago