Webhooks

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/

Setup

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.

Request

Supported events

Events currently supported by webhooks are visitor.signin, visitor.signout.

Schema

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

Site Object

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

Visitor Object

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
photo_url String A URL to an image of the visitor photo (optional)
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 & Personal Fields

Additional and personal fields are key value Objects.

{
  "field1": "value1",
  "field2": 789,
  "field3": true
}

Example

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",
    "photo_url": null,
    "badge_url": null,
    "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
  }, 
   "visiting": {
      "id": 8,
      "name": "Adele Vance",
      "role": "Retail Manager",
      "email": "AdeleV@2064mx.onmicrosoft.com",
      "mobile": ""
  }
}

Response

Sign In App expects a 2xx HTTP response code to acknowledge the request succeeded.

Errors

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

Signature verification provides a mechanism to authenticate the request has been sent by Sign In App. We do this by having a shared secret, filled in when setting up the webhook. While this is optional, it is recommended.

Example

When a webhook request is made to the webhook url, it will also include a HTTP header with the name x-signinapp-webhook-signature.

The header is made up of two parts separated by a comma. e.g. x-signinapp-webhook-signature: t=1644316744,s1=462fa402e927893dee0bfec09379718a507c883919442de3dcb1504142ceaa5d

The t value is a timestamp used to confirm when the webhook was sent.

The s1 value is a sha256 hmac of the timestamp from t concatenated with the http body.

Python example:

hmac.new("MySharedSecret", "timestamp.body", hashlib.sha256).hexdigest()

Substitute the shared secret, timestamp and http body. Note there is a fullstop seperating the timestamp and the http body.

You should be checking the outcome of this call matches s1 in the webhook request header.

Other code examples:

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));

Java:

String signedPayload = String.format("%d.%s", timestamp, payload);
String expectedSignature = Util.computeHmacSha256(secret, signedPayload);
Util.secureCompare(expectedSignature, signature)

© 2024 Sign In App Ltd