Webhook notifications allow Sign In App to send an alert to external applications when a visitor or staff member signs in or out. Webhooks are configured within notifications, so different rules can be set by site or visitor group. Advanced filters allow you to build your own workflow, sending different webhook notifications based on the data your visitors provide.
Caveat
Webhook events are not issued for the automatic sign out functionality. For example if the system is set to sign all visitors out at midnight, a webhook event won't be issued for each individual. If webhooks are being used in a data sync scenario, the best option is to use the history endpoint.
> curl -d '{...}' -X POST https://your.url/
Creating a notification is done through the Portal via Manage > Notifications. Add a new notification and select webhook as the channel. The requirements for a webhook are the URL endpoint and a secret key for the webhook signature.
More information about the setup of Notifications can be found in the Group notifications.
Supported events
Events currently supported by webhooks are visitor.signin
, visitor.signout
.
Key | Type | Description |
---|---|---|
event | String | Event Name |
event_at | String | Date of event (ISO8601 format) |
pushed_at | String | Date the event was pushed (ISO8601 format) |
idempotency_key | String | Unique key for the event |
site | Object | The site for the visitor the event happened on |
visitor | Object | The visitor the event happened for |
Key | Type | Description |
---|---|---|
id | Integer | Unique site identifier |
type | String | The site type, this can be standard or remote |
name | String | The name of the site |
timezone | String | The sites timezone |
Key | Type | Description |
---|---|---|
id | Integer | Unique visitor identifier |
returning_visitor_id | Integer | Unique returning visitor identifier, if set |
name | String | The name of the visitor |
badge_url | String | A URL to an image of the visitor badge (optional) |
additional | Object | Additional data recorded about the visitor |
personal_fields | Object | Personal fields associated with the (returning) visitor |
is_returning | Boolean | Whether the visitor is a known returning visitor |
is_pre_registered | Boolean | Whether the visitor was pre-registered |
is_remote | Boolean | Whether the visitor was considered remote |
Additional and personal fields are key value Objects
.
{
"field1": "value1",
"field2": 789,
"field3": true
}
The following is a formatted example of the data. A typical request body would not contain newlines and additional spaces.
{
"event": "visitor.signin",
"event_at": "2020-01-01T12:00:01Z",
"pushed_at": "2020-01-01T12:00:01Z",
"idempotency_key": "4EPAoqR4N8jZktby",
"site": {
"id": 4567,
"type": "standard",
"name": "Acme Co",
"timezone": "Europe/London"
},
"visitor": {
"id": 1234,
"name": "John Smith",
"badge_url": "",
"additional": {
"Company": "Acme Ltd",
"Email Address": "john@smith.com"
},
"personal_fields": {
"role": "Director",
"Car Reg": "ABC 123"
},
"is_returning": false,
"is_pre_registered": false,
"is_remote": false
}
}
Sign In App expects a 2xx HTTP response code to acknowledge the request succeeded.
When your end point responds with a HTTP status code that isn't considered a success, Sign In App will continue to retry for a maximum of 3 times before giving up.
Signature verification provides a mechanism to authenticate the request has been sent by Sign In App. While this is
optional, it is recommended. The signature is stored in the header of request. The signature comprises of a timestamp
and 1 to many signature hashes.
Hashed 256 with secret "timestamp.json-payload". It's important to take the payload without any additional formatting.
Request Header: X-SignInApp-Webhook-Signature
Header value is a comma separated list. t=timestamp,s1=signature,s2=signature
The timestamp is an integer UNIX timestamp value. All sX=
values are string hashes used to validate the request
payload.
Javascript:
const crypto = require('crypto');
crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + payload, 'utf8')
.digest('hex');
PHP:
$header = $request->getHeader('X-SignInApp-Webhook-Signature');
[$timestamp, $signature] = getSignatureParts($header);
hash_equals($signature, hash_hmac("sha256", "{$timestamp}.{$jsonEncodedPayload}", $secret));
Python:
payload = request.data
request.headers.get("X-SignInApp-Webhook-Signature", None)
hmac = hmac.new(secret.encode("utf-8"), msg=timestamp + '.' + payload, digestmod=hashlib.sha256)
valid = headerSignature == hmac.hexdigest()
Java:
String signedPayload = String.format("%d.%s", timestamp, payload);
String expectedSignature = Util.computeHmacSha256(secret, signedPayload);
Util.secureCompare(expectedSignature, signature)