> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frankieone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Event Notifications & Webhooks

<Info>
  To set up webhooks, contact [help@frankieone.com ](mailto:help@frankieone.com) with your designated webhook endpoint URL(s) and contact email. You can configure multiple webhook endpoints for different notification types. Ensure your endpoint is accessible via HTTPS.
</Info>

FrankieOne uses webhooks to send real-time notifications about events in your system, such as a workflow completing or an entity's risk profile changing. This allows you to build automated, event-driven integrations.

## Available Notifications

<CardGroup cols={2}>
  <Card title="Workflow Events" icon="arrows-rotate">
    Notifications triggered when a workflow execution completes, providing updates on the final status and outcome.
  </Card>

  <Card title="IDV Biometrics Events" icon="id-card">
    Notifications for IDV biometrics events, such as token requests, results retrieval, errors, and expirations.
  </Card>

  <Card title="Entity Events" icon="user">
    Notifications related to entity events, such as onboarding, updates, and errors.
  </Card>

  <Card title="Activity Monitoring Events" icon="chart-line">
    Notifications from financial transactions (deposits, withdrawals) or activities (registration, login) are checked for fraud, AML, or behavior risks and trigger alerts when operators act on them.
  </Card>
</CardGroup>

### Workflow Events

| Function           | Description                                                                                                                                                                                                     |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WorkflowComplete` | Sent when a workflow execution finishes, providing the final status and outcome. Also sent when there is an error during workflow execution — use the `functionResult` field to distinguish success from error. |

<Accordion title="Workflow Error Events">
  Notifications related to errors workflow events are sent to your webhook endpoint.

  | Notification Function | Description                                            |
  | --------------------- | ------------------------------------------------------ |
  | `WorkflowComplete`    | Sent when there is an error during workflow execution. |
</Accordion>

### IDV Biometrics Events

| Function            | Description                                                  |
| ------------------- | ------------------------------------------------------------ |
| `TOKEN_REQUESTED`   | Sent when a token is requested for IDV biometrics.           |
| `ONB_URL_GENERATED` | Sent when an onboarding URL is successfully generated.       |
| `RESULTS_RETRIEVED` | Sent when IDV biometrics results are successfully retrieved. |
| `OCR_PROCESSED`     | Sent when OCR processing is completed.                       |

These IDV function names are also sent when errors occur during the corresponding operation. Use the `functionResult` field to distinguish success from error.

<Accordion title="IDV Biometrics Error Events">
  Notifications related to errors in IDV biometrics events are sent to your webhook endpoint.

  | Notification Function | Description                                                          |
  | --------------------- | -------------------------------------------------------------------- |
  | `TOKEN_REQUESTED`     | Sent when there is an error during token request for IDV biometrics. |
  | `RESULTS_RETRIEVED`   | Sent when there is an error retrieving IDV biometrics results.       |
  | `OCR_PROCESSED`       | Sent when there is an error during OCR processing.                   |
  | `ONB_URL_GENERATED`   | Sent when there is an error generating the onboarding URL.           |
</Accordion>

### Entity Profile Events

| Function                | Description                                                                                                                                                                                                                                                        |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `EntityStatusChanged`   | Sent when the event status of an entity changes.<br /><br /><u>How it works</u><br />- Triggered immediately following the completion of a v2 workflow execution.<br />- It monitors changes to individual Event Statuses rather than a singular "Overall Status". |
| `EntityRiskChanged`     | Sent when the risk level of an entity profile changes.                                                                                                                                                                                                             |
| `EntityProfileUpdated`  | Sent when an entity profile is updated.                                                                                                                                                                                                                            |
| `EntityAssigneeChanged` | Sent when the assignee of an entity profile changes.                                                                                                                                                                                                               |

<br />

<Tip>
  **Migrating from V1?**

  Some webhook function names differ from their V1 counterparts and do not follow the same naming conventions. For example, V1's `EntityStatusChange` is `EntityStatusChanged` in V2. Refer to the [Migrating from V1](https://docs.frankieone.com/#migrating-from-v1) to see the key differences.
</Tip>

<Callout icon="thumbtack" iconType="regular" color="#1A6CFF">
  **Understanding Event Statuses**

  For a complete mapping of all values and their transition logic, please consult the [Event Statuses Reference Guide](https://docs.frankieone.com/docs/portal-statuses-and-tags#event-statuses).
</Callout>

<Callout icon="note" iconType="regular" color="#FFCA16">
  **Webhook Notification Model for Repeated Workflow Runs**

  Webhook notifications for workflow completion are sent per workflow execution. In the KYC webhook specification, the `WorkflowComplete `event is triggered each time a workflow execution finishes successfully. Each payload includes a unique `workflowExecutionId `representing that specific execution instance.

  If multiple workflow executions occur for the same entity, a separate webhook notification is generated for each execution. Webhooks are not aggregated across multiple runs.
</Callout>

### Transaction and Activity Monitoring Events

FrankieOne sends notifications to keep you informed about transaction and activity monitoring. These notifications are sent to your configured webhook endpoint.

| **Notification Function** | **Description**                                                                                                                                                                                                               |
| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ActivityAlertCreated`    | Sent when an alert has been detected and created for an activity (financial or non-financial). Emitted before workflow execution.  This notifies customers that there is a potential issue to review for a particular entity. |
| `ActivityAlertUpdated`    | Sent when an activity alert has been resolved into a finalized state (e.g., TPA, TPR, FP). This allows customers to trigger actions like releasing or blocking payments after they have been held for review.                 |

<CodeGroup>
  ```json ActivityAlertCreated with a non-transaction activity - No transactionId theme={null}
  {
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "function": "ActivityAlertCreated",
    "message": "Activity alert created",
    "notificationType": "EVENT",
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityCustomerReference": "customer-ref-12345",
    "channel": "api",
    "customAttributes": {
      "activityId": {"type": "string", "value": "01KAWDS1NMC8J4RBDSSPF24NSV"},
      "evaluationId": {"type": "string", "value": "01KAWDS1NMC8J4RBDSSPGA67KD"},
      "activityResultId": {"type": "string", "value": "01KAWDS1PBM4BKBKVYDCP5EXBW"},
      "processResultId": {"type": "string", "value": "01KAWDS1PBM4BKBKVYDCP5EXBW"},
      "activityResultClass": {"type": "string", "value": "FRAUD"},
      "activityAt": {"type": "datetime", "value": "2025-09-02T05:38:02Z"}
    }
  }
  ```

  ```json ActivityAlertCreated with a transactional activity - Has transaction ID theme={null}
  {
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "function": "ActivityAlertCreated",
    "message": "Activity alert created",
    "notificationType": "EVENT",
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityCustomerReference": "customer-ref-12345",
    "channel": "api",
    "customAttributes": {
      "activityId": {"type": "string", "value": "01KAWDS1NMC8J4RBDSSPF24NSV"},
      "evaluationId": {"type": "string", "value": "01KAWDS1NMC8J4RBDSSPGA67KD"},
      "activityResultId": {"type": "string", "value": "01KAWDS1PBM4BKBKVYDCP5EXBW"},
      "processResultId": {"type": "string", "value": "01KAWDS1PBM4BKBKVYDCP5EXBW"},
      "activityResultClass": {"type": "string", "value": "FRAUD"},
      "transactionIdentifier": {"type": "string", "value": "TXN123456789"},
      "activityAt": {"type": "datetime", "value": "2025-09-02T05:38:02Z"},
    }
  }
  ```

  ```json ActivityAlertUpdated - Has transaction ID theme={null}
  {
      "entityId": "12345678-1234-1234-4321-123487650912",
      "entityType": "INDIVIDUAL",
      "serviceName": "DEFAULT",
      "function": "ActivityAlertUpdated",
      "functionResult": "SUCCESS",
      "notificationType": "EVENT",
      "message": "Activity alert updated",
      "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
      "version": "2.0.0",
      "entityCustomerReference": "customer-ref-12345",
      "overallStatus": "REVIEW",
      "channel": "api",
      "customAttributes": {
        "activityId": {"type": "string", "value": "01KAWDS1NMC8J4RBDSSPF24NSV"},
        "evaluationId": {"type": "string", "value": "01KAWDS1NMC8J4RBDSSPGA67KD"},
        "activityResultId": {"type": "string", "value": "01KAWDS1PBM4BKBKVYDCP5EXBW"},
        "activityResultClass": {"type": "string", "value": "FRAUD"},
        "activityAt ": {"type": "string", "value": "2025-09-02T05:38:02.00036Z"}
      }
  }
  ```
</CodeGroup>

## Webhook Structure

<Callout icon="bell" iconType="regular" color="#FFCA16">
  You can configure your webhook endpoint to receive all notifications or only specific types, depending on your integration requirements. The `notificationType` field in the payload identifies the category of each notification.

  Event-specific fields in the payload are always populated with relevant values based on the event type, ensuring you have the necessary context for processing.
</Callout>

All V2 webhooks share a consistent structure. The payload contains two key fields, notificationType and function, which you should use to determine how to process the event.

notificationType: Indicates the nature of the update. For most V2 use cases, this will be EVENT.

function: This field specifies the exact event that occurred.

The payload for every webhook consists of a base schema of common fields, with additional event-specific fields included depending on the function.

<Danger>
  **Some webhook function names differ from their V1 counterparts.** They also do not follow the same naming conventions. Refer to the tables above for the correct function names.
</Danger>

### Endpoint Format

FrankieOne appends the `requestID` to your configured webhook endpoint:

```text theme={null}
https://your-domain.com/webhook-endpoint/{requestID}
```

### Base Payload Schema

These fields are present on every webhook notification.

| Field                     | Type   | Always Present | Description                                                                                                                                                                                                 |
| ------------------------- | ------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `version`                 | string | Yes            | The API version of the webhook payload.                                                                                                                                                                     |
| `entityId`                | string | Yes            | The unique identifier of the entity related to the event.                                                                                                                                                   |
| `function`                | string | Yes            | The specific event that triggered the notification. See [Available Notifications](#available-notifications).                                                                                                |
| `functionResult`          | string | Yes            | The outcome of the event. `SUCCESS` indicates the operation completed successfully. `FAILURE` indicates the operation encountered an error or could not be completed.                                       |
| `requestId`               | string | Yes            | The unique identifier of the API request that initiated the event.                                                                                                                                          |
| `notificationType`        | string | Yes            | The category of notification. One of `FUNCTION`, `RESULT`, `EVENT`, `ALERT`.                                                                                                                                |
| `message`                 | string | Yes            | A human-readable summary of the event.                                                                                                                                                                      |
| `entityCustomerReference` | string | No             | Your customer reference identifier, used for linking notifications to your internal records.                                                                                                                |
| `workflowExecutionId`     | string | No             | The unique identifier of the workflow execution. Present when a workflow triggers the event.                                                                                                                |
| `workflowName`            | string | No             | The name of the workflow that triggered the event.                                                                                                                                                          |
| `serviceName`             | string | No             | The name of the service profile involved.                                                                                                                                                                   |
| `entityType`              | string | No             | The type of entity (e.g., `INDIVIDUAL`).                                                                                                                                                                    |
| `overallRiskLevel`        | string | No             | The overall risk level of the entity. One of `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `UNACCEPTABLE`.                                                                                                            |
| `overallStatus`           | string | No             | The overall status of the entity. One of `UNCHECKED`, `IN_PROGRESS`, `REVIEW`, `PASS`, `FAIL`, `COMPLETE`, `INCOMPLETE`, `NEEDS_APPROVAL`, `APPROVED`, `REJECTED`, `BLOCKED`, `CLEAR`, `URGENT`, `MONITOR`. |
| `channel`                 | string | No             | The channel source from which the webhook was triggered. Present in v2 webhooks.                                                                                                                            |
| `assignee`                | string | No             | The assignee of the entity.                                                                                                                                                                                 |
| `customAttributes`        | object | No             | Custom attributes associated with the entity. Present in v2 webhooks when configured.                                                                                                                       |

### Event-Specific Fields

Depending on the `function`, additional fields may be present in the payload.

| Function              | Additional Fields                                      | Description                                             |
| --------------------- | ------------------------------------------------------ | ------------------------------------------------------- |
| `WorkflowComplete`    | `workflowExecutionId`, `workflowName`, `overallStatus` | Identifiers and final status of the completed workflow. |
| `EntityStatusChanged` | `overallStatus`                                        | The new overall status of the entity profile.           |
| `EntityRiskChanged`   | `overallRiskStatus`                                    | The new risk level of the entity profile.               |

### Payload Examples

<CodeGroup>
  ```json Workflow Complete theme={null}
  {
    "workflowExecutionId": "01JMX7F1Z61K0BP0KWY6MWAQ4J",
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "workflowName": "Onboarding",
    "serviceName": "DEFAULT",
    "function": "WorkflowComplete",
    "functionResult": "SUCCESS",
    "notificationType": "EVENT",
    "message": "Entity profile updated",
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityCustomerReference": "customer-ref-12345",
    "overallStatus": "REVIEW",
    "channel": "api"
  }
  ```

  ```json Entity Risk Changed theme={null}
  {
    "workflowExecutionId": "01JMX7F1Z61K0BP0KWY6MWAQ4J",
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "workflowName": "Onboarding",
    "serviceName": "DEFAULT",
    "function": "EntityRiskChanged",
    "functionResult": "SUCCESS",
    "notificationType": "EVENT",
    "message": "Entity profile updated",
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityCustomerReference": "customer-ref-12345",
    "overallRiskStatus": "LOW",
    "channel": "api"
  }
  ```

  ```json Entity Status Changed theme={null}
  {
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "entityCustomerReference": "customer-ref-12345",
    "function": "EntityStatusChanged",
    "functionResult": "SUCCESS",
    "notificationType": "EVENT",
    "channel": "api",
    "serviceName": "DEFAULT",
    "assignee": "john.doe@example.com",
    "workflowExecutionId": "01JMX7F1Z61K0BP0KWY6MWAQ4J",
    "workflowName": "Onboarding",
    "message": "Entity status changed from 'UNCHECKED' to 'PASS'",
    "overallStatus": "PASS"
  }
  ```

  ```json Entity Profile Updated theme={null}
  {
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "entityCustomerReference": "customer-ref-12345",
    "function": "EntityProfileUpdated",
    "functionResult": "SUCCESS",
    "notificationType": "EVENT",
    "channel": "api",
    "message": "Entity profile updated"
  }
  ```

  ```json Entity Assignee Changed theme={null}
  {
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "entityCustomerReference": "customer-ref-12345",
    "function": "EntityAssigneeChanged",
    "functionResult": "SUCCESS",
    "notificationType": "EVENT",
    "channel": "api",
    "serviceName": "DEFAULT",
    "assignee": "jane.smith@example.com",
    "workflowExecutionId": "01JMX7F1Z61K0BP0KWY6MWAQ4J",
    "workflowName": "Onboarding",
    "message": "Entity assignee changed from 'john.doe@example.com' to 'jane.smith@example.com'"
  }
  ```

  ```json Document Processing (IDV) theme={null}
  {
    "workflowExecutionId": "01JMX7F1Z61K0BP0KWY6MWAQ4J",
    "entityId": "12345678-1234-1234-4321-123487650912",
    "entityType": "INDIVIDUAL",
    "workflowName": "DocumentProcessing",
    "serviceName": "IDV",
    "function": "OCR_ERROR",
    "functionResult": "FAILURE",
    "notificationType": "EVENT",
    "message": "Error encountered while processing OCR data.",
    "requestId": "01EKVV810DC7NJEC97BAQJZXWR",
    "version": "2.0.0",
    "entityCustomerReference": "customer-ref-12345",
    "overallStatus": "FAILED",
    "channel": "api"
  }
  ```
</CodeGroup>

***

## Handling Notifications

### 1. Receive the Webhook

Your endpoint should respond with a `200` or `202` HTTP status code to acknowledge receipt.

* If your endpoint returns a `5xx` or `4xx` status code (other than `400`), the system retries delivery.
* A `400` response stops retries immediately.

### 2. Process the Notification

Use the `notificationType` and `function` fields to determine the appropriate action. Use `functionResult` to distinguish successful events from errors.

### 3. Retrieve Workflow Execution Results

After receiving a `WorkflowComplete` notification, retrieve the full workflow execution results by calling:

```text theme={null}
GET /v2/individuals/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/executions/{workflowExecutionId}
```

This endpoint is documented in the OpenAPI spec and available in the Postman collection. All path parameters (`entityId`, `serviceName`, `workflowName`, `workflowExecutionId`) are provided in the webhook payload.

Required headers:

| Header                 | Description                  |
| ---------------------- | ---------------------------- |
| `api_key`              | Your FrankieOne API key.     |
| `X-Frankie-CustomerID` | Your FrankieOne customer ID. |

## Security

### HTTPS and IP Whitelisting

All webhook payloads are delivered over HTTPS. FrankieOne supports IP whitelisting so you can restrict incoming requests to known FrankieOne IP addresses. See [Outbound IP Addresses](/reference/outbound-ip-addresses) for the list of IPs to whitelist.

### JWT Authentication (Optional)

You can enable JSON Web Token (JWT) signing for additional payload verification. Contact [support@frankieone.com](mailto:support@frankieone.com) to enable JWT verification for your account.

When enabled, the JWT is included in the `Authorization` header of the webhook request using the Bearer scheme:

```http theme={null}
Authorization: Bearer <base64 header>.<base64 body>.<base64 signature>
```

The JWT has the following structure:

**Header:**

```json theme={null}
{
  "alg": "RS256",
  "typ": "JWT"
}
```

**Body:**

```json theme={null}
{
  "sub": "[email protected]",
  "iat": 1516239022,
  "iss": "io.frankiefinancial.kycaml"
}
```

| Field | Description                                                   |
| ----- | ------------------------------------------------------------- |
| `sub` | The subject. Present for portal-triggered notifications only. |
| `iat` | Issued-at timestamp (UTC epoch, seconds).                     |
| `iss` | Issuer. Fixed value: `io.frankiefinancial.kycaml`.            |

**Security details:**

* RSA-4096 bit private key encryption.
* A customer-specific public key is provided for verification.
* HTTPS transport with secure algorithms.

***

## Retry Mechanism

FrankieOne retries failed webhook deliveries using the following approach:

1. **Initial Retry:** Immediately after the first failure.
2. **Exponential Backoff:** Subsequent retries occur at increasing intervals.
3. **Maximum Retries:** Up to 50 attempts over approximately 24 hours.

If all retries fail, the message is moved to a Dead Letter Queue (DLQ) and the FrankieOne support team is notified. Contact [support@frankieone.com](mailto:support@frankieone.com) to retrieve messages from the DLQ if necessary.

***

## Best Practices

* **Respond quickly.** Return a `200` or `202` from your webhook endpoint as fast as possible. Perform any heavy processing asynchronously after acknowledging receipt.
* **Handle duplicates.** Due to retries, your endpoint may receive the same notification more than once. Use the `requestId` field to deduplicate.
* **Check `functionResult`.** The same `function` name (e.g., `WorkflowComplete`, `TOKEN_REQUESTED`) is used for both success and error events. Always check `functionResult` to determine the outcome.
* **Use the retrieval endpoint.** Webhook payloads contain summary information. For full workflow execution details, always call the retrieval endpoint using the identifiers provided in the payload.

***

## Migrating from V1

Key differences between V1 and V2 webhook notifications:

| Aspect               | V1                                              | V2                                                                                                                       |
| -------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Function names**   | `EntityStatusChange`                            | `EntityStatusChanged`                                                                                                    |
|                      | `EntityRiskChange`                              | `EntityRiskChanged`                                                                                                      |
|                      | `EntityProfileChange`                           | `EntityProfileUpdated`                                                                                                   |
|                      | `EntityAssigneeChange`                          | `EntityAssigneeChanged`                                                                                                  |
|                      | Per-operation names (e.g., `CreateCheckEntity`) | `WorkflowComplete` (single event for all workflow completions)                                                           |
| **Payload fields**   | `checkId` present in some payloads              | `workflowExecutionId`, `workflowName`, `entityType`, `entityCustomerReference`, `serviceName`, `channel` added           |
| **Result retrieval** | `GET /v1/retrieve/{requestID}`                  | `GET /v2/individuals/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/executions/{workflowExecutionId}` |
