Login

StackOne Webhooks

Describes how to use the StackOne webhooks functionality

Overview

StackOne allows configuring multiple Webhooks to establish alerts' communication between your application and StackOne servers. After creating a webhook, you will need to test Webhooks by specifying:
– example payload
– your customized webhook integration code

Create a webhook

  1. After selecting a StackOne project, you will see the Webhooks section in the left-hand-side menu. Click on it or open the Webhooks section directly.

  2. You can now create and configure a new webhook by clicking the Add Webhook button

  3. Select the events that your webhook should be triggered on.

    1. StackOne leverages synthetic webhooks by polling the underlying provider records every hour and comparing stored hashes. The poll time can be adapted based on your needs and no PII is stored as part of this process.
  4. Input in the Webhook URL field a valid URL that StackOne should send a request to whenever one of the previously selected event occurs.

  5. Finally, click on the Create Webhook button. You should now see the webhook on the webhooks page.

    1. A secret will be generated. This Signing secret will allow you to verify within your codebase that the request received at the given endpoint is a legitimate request sent by StackOne.
Webhooks creation demo

event list and associated record_type

record_typeAPIEventsSynthetic Webhook
account/account.created account.updated account.deletedReal-time
employees/hrishris_employees.created hris_employees.updated```hris_employees.deletedβœ…
employments/hrishris_employments.created hris_employments.updated hris_employments.deletedβœ…
interviews/atsats_interviews.created ats_interviews.updated ats_interviews.deletedβœ…
applications/atsats_applications.created ats_applications.updated ats_applications.deletedβœ…
candidates/atsats_candidates.created ats_candidates.updated ats_candidates.deletedβœ…
job_postings/atsats_job_postings.created ats_job_postings.updated ats_job_postings.deletedβœ…

πŸ“

Note:

The webhook settings such as URL and Events can be updated at any point after creating the webhook by returning to the Webhooks page and clicking on the webhook you would like to update.
You can also delete the webhook if it's no longer needed (irreversible action).

Testing Webhooks

Example Payload

Accounts-based webhooks payload will follow the following interface:

{
  project_id: string, // the ID of the StackOne project
  event: 'account.updated' | 'account.created' | 'account.deleted' | 'hris_employees.updated', 'hris_employees.created',
  event_date: 'string', // date as ISO string (eg: '2023-07-03T01:55:47.217Z')
  record_type: 'account',
  record_id: string | number, // In the case of accounts-based events - this will be the account ID
  sent_at: 'string', // date as ISO string (eg: '2023-07-03T01:55:47.217Z')
  account_id: string, // This will always be the Account ID
}

Account updated example

{
  "project_id": "acmeinc-27270",
  "account_id": "41220118784113397989",
  "event": "account.updated",
  "event_date": "2023-11-01T13:10:31.408Z",
  "record_type": "account",
  "record_id": "41220118784113397989",
  "sent_at": "2023-11-01T13:10:31.418Z"
}

Employee updated example

{
  "project_id": "acmeinc-27270",
  "account_id": "41260118784113327989",
  "event": "hris_employees.updated",
  "event_date": "2023-11-01T15:09:22.961Z",
  "record_type": "employees",
  "record_id": "3223323715753018140",
  "sent_at": "2023-11-01T15:09:22.978Z"
}

A x-stackone-signature header will be added to all webhook requests, e.g.,'x-stackone-signature': 'jqzLV78Lkg5RhZgx6nRA1FLIYBkqoclBdRrNizjlZcU'. This header will contain a hmac sha256 hash of the given payload using the Signature Secret previously given as a secret key during hashing.

⚠️

3rd party Webhook generators:

You can easily test the account-based webhooks by using a third-party webhook creation tool such as https://webhook.site or https://typedwebhook.tools/.

StackOne is not affiliated with these websites.

Sample Webhook consumer code

// index.js
import express from 'express';
import bodyParser from 'body-parser';
import { createHmac } from 'crypto';
const app = express();

// Replace with the signing secret string displayed on the Stackone webhooks details page
const STACKONE_WEBHOOK_SIGNATURE =
  'S-gQTtwraolKVsY88OvQNZ-TlGrHw9mvHKp-ls8Co9CkOADQc1VSeCZ_2hDK6oWuKUd_4qxjRLzoEGYA9JVCNg';


/**
 * The function checks if a given signature is valid by comparing it with the payload hash using a signing secret.
 * @param signature - The `signature` parameter is the signature value that you want to validate. It is typically a string
 * representing the cryptographic signature of the `payload` parameter.
 * @param payload - The payload is the data that needs to be signed. It can be any string or object that you want to verify
 * the integrity of.
 * @param signingSecret - The `signingSecret` parameter is a secret key used for generating the signature. It is a string
 * value that should be kept confidential and known only to the parties involved in the signature verification process.
 * @returns a boolean value indicating whether the calculated hash is equal to the provided signature.
 */
function isSignatureValid(signature, payload, signingSecret) {
  const hash = createHmac('sha256', signingSecret)
    .update(payload)
    .digest('base64url');
  return hash === signature;
}

const jsonParser = bodyParser.json();

app.post('/integrations/webhook/accounts', jsonParser, (req, res) => {
  const signature = req.headers['x-stackone-signature'];
  if (
    !signature ||
    !isSignatureValid(
      req.headers['x-stackone-signature'],
      JSON.stringify(req.body),
      STACKONE_WEBHOOK_SIGNATURE,
    )
  ) {
    return res.status(401).send('Unauthorized');
  }
  // Do something with the payload
  console.log(req.body);

  // The webhook URL should return a 200 upon successful processing of the event. The response does not need to include anything else.
  return res.status(200).send(`Thank you for the account webhook event ❀️`);
});

console.log('listening on port 3333');
app.listen(3333);

// This sample server can be run via `node index.js`