Webhooks allow you to receive notifications from Frigade when certain events occur. You can use webhooks to receive notifications about your users when they start a Flow and as they progress through it.

Creating a webhook

To add a new webhook, open the Webhooks page from the left sidebar in the Frigade dashboard and click the “New webhook” button.

Supported events

The following events are currently supported:

flowResponse.startedFlow
When a user starts a Flow
flowResponse.completedFlow
When a user completes a Flow
flowResponse.skippedFlow
When a user dismisses/skips a Flow
flowResponse.startedStep
When a user starts a Step in a Flow
flowResponse.completedStep
When a user completes a Step in a Flow

Webhook payload

The payload of the message includes the type of the event in the type property.

The data property contains the actual payload sent by Frigade. The payload can be a different object depending on the event type.

The below example shows the payload for a flowResponse.completedFlow event for the NPS Survey component:

{
  "timeout": 1000,
  "data__nps-feedback-page__nps-feedback-text": "I love the service!",
  "data__nps-score-page__nps-score": 10,
  "data__id": "flowResponse_uPzbTOayngU00Vzc",
  "data__flowId": "flow_8Lq7hAqA",
  "data__flowSlug": "flow_8Lq7hAqA",
  "data__userId": 53526,
  "data__userSlug": "user_qnsDyTeZxP2sl12Q",
  "data__actionType": "COMPLETED_FLOW",
  "data__data": "{}",
  "data__stepId": "nps-feedback-page",
  "data__blocked": false,
  "data__hidden": false,
  "user__name": "",
  "user__email": null,
  "user__id": "abcdefgh",
  "flow__id": "flow_8Lq7hAqA",
  "flow__name": "NPS Survey",
  "type": "flowResponse.completedFlow",
  "data": {
    "nps-feedback-page": {
      "nps-feedback-text": "I love the service!"
    },
    "nps-score-page": {
      "nps-score": 10
    },
    "id": "flowResponse_uPzbTOayngU00Vzc",
    "flowId": "flow_8Lq7hAqA",
    "flowSlug": "flow_8Lq7hAqA",
    "userId": 53526,
    "userSlug": "user_qnsDyTeZxP2sl12Q",
    "actionType": "COMPLETED_FLOW",
    "data": "{}",
    "stepId": "nps-feedback-page",
    "createdAt": "2024-08-21T16:31:36.187Z",
    "foreignUserId": "abcdefgh",
    "blocked": false,
    "hidden": false
  },
  "time": "2024-08-21T16:31:36.207Z",
  "user": {
    "name": "",
    "email": null,
    "id": "abcdefgh"
  },
  "flow": {
    "id": "flow_8Lq7hAqA",
    "name": "NPS Survey"
  },
  "signature": "xhOBcleUmA9wahBlLHAhZA9l6BgDF2vuR3GFVU1lGxE="
}

Verifying webhooks

When you create a webhook, Frigade will generate a secret key for you. You can use this key to verify that the webhook is coming from Frigade.

If you don’t verify the request, your app will be susceptible to a number of attacks since your webhook endpoint is open to the public.

To verify the request, you need to calculate the HMAC SHA256 hex digest of the JSON-encoded data field using the secret key as the key and compare it to the value signature field. Note that when JSON-encoding the data field it needs to match the order of the keys in the payload and not contain any whitespace between the keys and values.

For example, in Node.js, you can do it like this:

const crypto = require('crypto');

const payload = {
  type: 'flowResponse.completedStep',
  signature: 'cabff19d9da06705f62c26c2a66154',
  time: '2020-01-01T00:00:00.000Z',
  data: {
    // flowResponse object
  },
};

function verifySignature(secret, payload) {
  return (
    crypto
      // sign the string with sha256 using your secret
      .createHmac('sha256', secret)
      // If payload is already decoded, you need to stringify it first
      .update(Buffer.from(JSON.stringify(payload.data), 'utf-8'))
      // base64 encode it
      .digest('base64')
  );
}

const signature = verifySignature('secret', payload);

if (signature !== payload.signature) {
  throw new Error('Invalid signature');
}

Verifying timestamps

The time field in the payload is the time when the event occurred. You can use this field to verify that the request is not a replay attack by ignoring older events.

Retrying failed requests

Frigade will retry failed requests up to 5 times with an exponential backoff strategy.

Common fields

The following fields are available in all Frigade webhooks (shown in flattened format):

  • flow__id: The ID of the Flow that triggered the webhook
  • flow__name: The name of the Flow that triggered the webhook
  • user__id: The ID of the user that triggered the webhook
  • user__name: The name of the user that triggered the webhook (if available)
  • user__email: The email of the user that triggered the webhook (if available)