# Event Notification Webhook

An event notification webhook can notify your systems when events occur within your SQR digital identity environment or dashboard.
When an event is triggered, SQR sends an HTTPS `POST` request to your configured webhook URL containing a JSON payload and delivery metadata headers.

Webhooks reduce the need to poll B2B API endpoints, improving efficiency and minimising orchestration overhead.

A single target webhook is supported per SQR environment.

**HTTP Request**

- HTTP method: `POST`
- Content-Type: `application/json; charset=utf-8`
- Body: `JSON event envelope` *(see “Request Body”)*


### Supported Event Types

Webhook notifications are supported by the following identity event types;

- `USER_STATUS_CHANGED` — fires when a user's registration status changes.
- `FLAG_STATUS_CHANGED` — fires when an Ongoing Monitoring (OGM) flag status changes for a user, including PEP, Sanction, and Adverse Media checks.


### Request Body

The webhook body is a JSON object with a standard envelope.

| Field | Type | Description |
|  --- | --- | --- |
| `event_id` | string | Unique identifier for the event |
| `event_type` | string | Event type code |
| `occurred_at` | string (ISO-8601) | When the event occurred (UTC) |
| `version` | string | Schema version for the event envelope |
| `data` | object | Event-specific payload |


**Example Request Body**


```
{
  "event_id": "a1ba123b-dda9-4ceb-debd-813c34a04925",
  "event_type": "USER_STATUS_CHANGED",
  "occurred_at": "2025-12-01T14:34:48.435Z",
  "version": "2",
  "data": {
    "user_id": "ZZZZZZZZZZZZZZZZ",
    "client_id": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
    "registration_status": "Incomplete",
    "registration_status_code": "INCOMPLETE"
  }
}
```

### Request Headers

Each webhook request includes the following headers to help you verify authenticity (HMAC signature), prevent replay, and deduplicate retries.

- `x_signature`, Hex-encoded HMAC-SHA256 signature of the raw JSON request body (64 hex characters).
- `x_timestamp`, ISO-8601 timestamp (UTC) for replay protection and traceability.
- `x_event_id`, Event identifier used for traceability and idempotency.
- `content-type`, application/json



```
{

  "x_signature": "75a37300000000000006811a2059b1eb51cdb14c7571ade3b5c54dccf9ad560fed",
  "x_timestamp": "2025-12-01T14:34:51.862Z",
  "x_event_id": "f1fa123b-dda9-4cbb-aeba-877c15a0e985",
  "content-type": "application/json",
}
```

#### Signature Verification

The header signature, `x_signature` is computed over the raw JSON request body using the following parameters.

- Algorithm: `HMAC-SHA256`
- Key: `your shared webhook secret`
- Input: `UTF-8 bytes of the raw request body`


Resulting in a lowercase hex-encoded signature.

`x_signature` provides cryptographic integrity and authenticity for each webhook delivery.

It allows you to verify that the request body was generated by SQR, meaning the sender had access to the shared secret, and that the payload has not been modified in transit. Any change to the body, even a single character, results in a different signature and can be detected before you process the event.

Use of the `x_signature` is recommended, but it is not required for webhook operation.

To validate `x_signature`, compute the HMAC using the raw request body bytes exactly as received (before JSON parsing).
Do not parse and re-serialize JSON for verification, as formatting differences can change the bytes and break signature checks.

#### Idempotency and Retries

Webhook delivery may be retried on failure. Customers should implement idempotent handling as follows.

- Use `x_event_id` (or `event_id`) as the idempotency key.
- Store processed event IDs for future validation.
- If the same event is received again, return 2xx without re-processing.


### FLAG_STATUS_CHANGED Event

The `FLAG_STATUS_CHANGED` event is fired when a PEP, Sanction, or Adverse Media (Ongoing Monitoring) flag status is updated for a connected user. This enables relying parties to react in real time to OGM screening outcomes without polling the User Status endpoint.

#### Data Payload Fields

| Field | Type | Description |
|  --- | --- | --- |
| `user_id` | string | Unique identifier of the user |
| `client_id` | string (UUID) | Identifier of the relying party (client) the user is connected to |
| `flag_type` | string | The OGM check type. One of: `PEP`, `SANCTION`, `ADVERSE_MEDIA` |
| `previous_flag_status` | string | null | The flag status before this change, or `null` if this is the initial status |
| `new_flag_status` | string | The updated flag status after this change |
| `triggered_by` | string | null | Identifier of the actor who triggered the status change, or `null` if system-initiated |


#### Flag Status Values

| Value | Description |
|  --- | --- |
| `Pending` | The flag check result is awaiting review |
| `For Review` | The flag has been escalated and requires manual review |
| `Flagged` | The flag has been confirmed, the user is actively flagged |
| `Cleared` | The flag has been reviewed and the user has been cleared |


#### Example Request Body


```json
{
  "event_id": "b2cb234c-eeb0-5dfc-efce-924d45b15036",
  "event_type": "FLAG_STATUS_CHANGED",
  "occurred_at": "2025-12-01T14:34:48.435Z",
  "version": "1",
  "data": {
    "user_id": "ZZZZZZZZZZZZZZZZ",
    "client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "flag_type": "PEP",
    "previous_flag_status": "Pending",
    "new_flag_status": "For Review",
    "triggered_by": null
  }
}
```

### Expected (HTTP) Responses

Your webhook endpoint should return one of the following HTTP status code ranges;

- `2xx`: Successfully received and accepted for processing, including duplicate deliveries that you have safely ignored.
- `4xx`: The request is invalid and should not be retried (for example, signature verification failed or the JSON payload is malformed).
- `5xx`: A temporary error occurred on your side and the delivery may be retried.


#### Error Handling Expectations

Recommended behaviours;

- `401 Unauthorized` if signature verification fails
- `400 Bad Request` if required fields are missing/invalid
- `200 OK` for successful processing


### Security Considerations

When implementing webhook endpoints, please consider the following areas.

- Your endpoint must enforce HTTPS with TLS 1.2 or higher.
- Keep the webhook secret confidential, restrict access, and rotate it periodically in line with your security policy.
- We recommend logging `x_event_id`, `x_timestamp`, and any signature verification failures to support troubleshooting and audit requirements.