A webhook is a common way to get updated of certain changes, such as when an authentication is completed. You register a https URL where the event data can be stored in JSON or XML formats. Webhooks are used differently for different APIs. For the SMS API we send a webhook each time the SMS delivery status changes. Note that this may happen several times. ## Webhook success Swedish BankID response example (json) Normally the response body contains the same data as a normal collect result API call would return: ``` { "identity": { "CountryCode": "SE", "FirstName": "LARS", "LastName": "SVENSSON", "FullName": "LARS SVENSSON", "PersonalNumber": "191212121212", "DateOfBirth": "1912-12-12", "Age": 107, "IdProviderName": "BankIDSE", "IdentificationDate": "2018-10-22T08:26:41.8675683+02:00", "IdProviderRequestId": "", "IdProviderPersonId": "", "CustomerPersonId": "" }, "BankIDSE": { "signature": "PD94….", "ocspResponse": "MIIH…" }, "method": "sbid-another", "id": "61d300c2-cff8-4dc1-9abc-6d59f8876d32" } ``` ### Configuring your webhook settings You need to provide ZignSec with a http URL you would like to receive webhooks on. There are some tools that can help the development, for example, RequestBin, Pagekite and ngrok. If you are unsure please contact ZignSec for help with setting up your integration. ### Receiving a webhook Once you have registered a webhook we will send HTTP POST calls to the specified URL each time an event occurs. POST data contains relevant information from the event that triggered the request. To acknowledge that you have received data of a webhook, your endpoint should return a 2xx HTTP status code. If a webhook for any reason is not received correctly, ZignSec will retry 3 times. It is important that a webhook answered as quickly as possible. It is recommended to wait to process until after a response has been sent. ### Verify a webhook created through the API Webhooks created through the API can be verified by calculating a digital signature. X-ZignSec-Hmac-SHA256 header which is generated using the AppID secret you have from ZignSec. It also uses the data sent in the request. Please note that this feature is available for eid’s with the `test.zignsec.com/v2/` and `api.zignsec.com/v2/` endpoints. We are currently working with adding verification for our other implementations.  It is also possible to use IP whitelisting to confirm the origin of a webhook. To verify that a webhook comes from ZignSec calculate the HMAC digest according to the algorithm below, and compare with the X-ZignSec-Hmac-SHA256 header. If they match, you can be sure that the Webhook was sent from ZignSec and the data has not been compromised.  ``` byte[] data = Encoding.UTF8.GetBytes(postedJSONString); using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(yourPersonalAccessTokenString))) { callbackRequest.Headers.Add("X-ZignSec-Hmac-SHA256", System.Convert.ToBase64String(hmac.ComputeHash(data))); } ``` # Test Webhook endpoint ZignSec provide API that you can use to test webhooks of your services from ZignSec side. This is the list of IP addresses of ZignSec servers:  Outbound IP addresses: 137.117.208.108, 137.117.208.41, 137.117.211.152 Additional outbound IP addresses: 137.117.218.101, 137.117.210.101, 137.117.214.210, 137.117.214.88, 137.117.212.13, 137.117.208.108, 137.117.208.41, 137.117.211.152 ### API [POST to https://`env`.zignsec.com/v2/webhook/test](https://docs.zignsec.com/api/v2/searchperson-2-2/#searchperson) where `env` is API or test. ### Request Parameters | | | |---|---| |Url|Mandatory parameter. URL of client service for callbacks.| ### Example request for a Webhook test ``` POST https://test.zignsec.com/v2/webhook/test HTTP/1.1 Content-Type: application/json; charset=UTF-8 Authorization: your_key_here { "Url": "https://webhook.site/480d113a-83fe-47b1-8c83-3d2479465348" } ``` ### Response | | | |---|---| |`elapsed`|Webhook call in milliseconds.| |`statusCode`|Status code of HTTP request.| |`error`|Error code.| |`errorMessage`|​Error message.| ### Example response for a Webhook test ``` { "elapsed": 1288, "statusCode": 200, "error": null, "errorMessage": null } ```