Configuration Change Webhooks

1. Purpose

Today, when a tenant’s historyDays value (per domain) or Authorization filter changes, nothing tells the customer that the configuration itself changed — they only see the downstream ripple, entity by entity, once a load happens to run. A single configuration change can silently affect a large, unbounded set of records, so incremental sync isn’t a reliable way to catch every impacted entity.

HISTORICALDAYS_CHANGED and AUTHORIZATION_CHANGED events close that gap: the moment either configuration value is updated, the tenant gets an explicit, actionable signal — “your configuration changed, trigger a Full Data load now to get an accurate, complete view of which entities are now visible or hidden.” This turns an invisible, confusing bulk visibility shift into a clear notification, rather than leaving the customer to infer the cause from scattered per-entity Archive/Unarchive/Authorize/Unauthorize events with no context on what triggered them.

We do not trigger the Full Data load ourselves. Both events are documented as the recommended trigger for the customer to initiate one; the load itself remains the customer’s action.


2. The configuration objects behind these events

Both events report changes to the configuration. Understanding these two objects is necessary to understand what the webhooks report.

History Days

Defined per tenant and domain, it states:

  • the historical limit, in days, of closed data the API can still return. Any closed item older than currentDate + historyDays (relative to its closing date) is not shown.
  • Setting historyDays to 0 means no historical data at all is retrieved for that domain — every endpoint stops showing closed data once it reaches its closing date. This change impacts all endpoints of that domain, not a single entity.

Filters

Defined per tenant + domain + clientId, the authorization filter shapes what that client can see, and whether that client receives webhooks:

  • one or more { Field, Operand, Values } statements (e.g. EmploymentType In ['T']).
  • Field can be EmploymentType, Classification, PayrollClientCode, PayrollInstitutionCode, companyCode, employmentTypeName.

3. The two events

Event Fires when… Scope
HISTORICALDAYS_CHANGED The historyDays value for a domain subscription changes One event per tenant + domain
AUTHORIZATION_CHANGED The Authorization filter for a domain changes One event per tenant + domain

Both:

  • Have operation: Update only — there is no Insert or Delete variant for either event.
  • Fire unconditionally on config update, regardless of whether any existing record is actually impacted — impact isn’t known at config-change time, so the event fires either way.
  • Follow the standard duplicate rule: if the same event/operation is received more than once, the message with the latest timestamp is authoritative.

4. Payload examples

HISTORICALDAYS_CHANGED — reduced from 90 to 30 days for domain wfm

{
  "tenantId": "12458",
  "domain": "wfm",
  "operation": "Update",
  "changedFields": {
    "historicalDays": {
      "oldValue": 90,
      "newValue": 30
    }
  },
  "timestamp": "2025-03-27T10:16:45.9780823+00:00",
  "value": {
    "historicalDays": 30
  }
}

AUTHORIZATION_CHANGED — peopleFilter values updated for domain wfm

{
  "tenantId": "12458",
  "domain": "wfm",
  "operation": "Update",
  "changedFields": {
    "peopleFilter": {
      "oldValue": { "field": "EmploymentType", "operand": "notin", "values": ["2", "1"] },
      "newValue": { "field": "EmploymentType", "operand": "notin", "values": ["8", "1"] }
    }
  },
  "timestamp": "2025-03-27T10:16:45.9780823+00:00",
  "value": {
    "peopleFilter": [
      { "field": "EmploymentType", "operand": "notin", "values": ["8", "1"] }
    ],
    "peopleFilterSelectAll": false
  }
}

AUTHORIZATION_CHANGED — peopleFilterSelectAll toggled from true to false for domain wfm

{
  "tenantId": "12458",
  "domain": "wfm",
  "operation": "Update",
  "changedFields": {
    "peopleFilterSelectAll": {
      "oldValue": true,
      "newValue": false
    }
  },
  "timestamp": "2025-03-27T10:16:45.9780823+00:00",
  "value": {
    "peopleFilter": [
      { "field": "EmploymentType", "operand": "notin", "values": ["8", "1"] }
    ],
    "peopleFilterSelectAll": false
  }
}

5. Example flow

  1. Customer reduces historyDays for domain wfm from 90 to 30 days.
  2. A HISTORICALDAYS_CHANGED/Update webhook is sent immediately.
  3. Customer triggers a Full Data load on their end.
  4. Customer discovers employment1 (discharged 60 days ago) is now archived and no longer visible — a consequence they learned about proactively, rather than by noticing a gap in incremental sync.

The same flow applies symmetrically for a widened historyDays window (records becoming visible again) and for narrowing/widening an AUTHORIZATION_CHANGED filter.