# Webhook Management

Webhooks are managed through the **Integration tab** in the Workforce Dashboard. From here, you can:

- **Add new webhooks**: Define a webhook name, event type, destination URL, and custom headers.
- **View existing webhooks**: See all configured webhooks in a list, including their event type, destination URL, and actions.
- **Edit or delete webhooks**: Update webhook settings or remove them as needed.

## Adding a New Webhook

To add a webhook, follow these steps:

1. **Open the Integration Tab**: Navigate to the Webhooks section.
2. **Click “Add New Webhook”**: This will open a setup form.
3. **Configure Webhook Details**:
   
   - **Webhook Name**: Enter a unique and descriptive name (e.g., “Verification Updates”).
   - **Event Type**: Select the type of event you wish to monitor (e.g., Verification Started, Verification Failed).
   - **Destination URL**: Provide the endpoint URL where notifications should be sent (e.g., `https://yourdomain.com/webhooks`).
   - **Custom Headers (Optional)**: Add any required custom header key-value pairs. Use custom headers for authentication or metadata required by your system.
4. **Save the Webhook**: Click “Save” to register the webhook.

## Viewing and Managing Webhooks

Once configured, all webhooks will be displayed in a tabular format, showing:

- **Name**: The webhook name for identification.
- **Event**: The event type the webhook listens for.
- **Destination URL**: The endpoint where notifications are sent.
- **Actions**: Options to edit or delete the webhook.

# Available Webhook Events

The table below outlines the supported webhook events:

| **Event Name** | **Event Type** | **Description** |
| --- | --- | --- |
| **Identity Enrolled** | `identity.enrolled` | Triggered when an identity is first verified in your organization. |
| **Verification Started** | `verification.started` | Triggered when a verification attempt begins. |
| **Verification Succeeded** | `verification.succeeded` | Triggered when a verification attempt succeeds. Allows retrieval of user data tied to the verification ID. |
| **Verification Failed** | `verification.failed` | Triggered when a verification attempt fails. Includes detailed failure reasons such as face match failure. |
| **Data sharing consent revoked** | `identity.revoked` | Triggered when a user deletes their Incode identity or revoke data sharing consent with your organization. |
| **Pending Manual Review** | `verification.failed` | Triggered when an employee's identity attribute doesn't match what's store in the employee's IAM profile. |

## Notification Payload Details

Each webhook notification includes common fields for tracking and context.

All requests come as `POST` requests to the endpoint configured. Headers are passed as key value pairs as configure. Payload is sent in JSON format. In your internal settings make sure that `Accept Application/json` is configured.

### Common Fields for All Webhook Notifications

| **Field** | **Type** | **Description** |
| --- | --- | --- |
| `event_id` | `string` | Unique identifier for the notification event. |
| `event_type` | `string` | Type of event triggering the webhook (e.g., `verification.failed`). |
| `timestamp` | `string` | UTC timestamp of the event in ISO 8601 format |
| `correlation_id` | `string` | Optional; You can provide an internal identifier at the start of verification |
| `data` | `object` | As described for each event type below |

### Webhook: Identity Enrolled

| **Field** | **Type** | **Description** |
| --- | --- | --- |
| `integration_id` | `string` | Identifier for the integration for which verification has been requested. |
| `identity_id` | `string` | Unique identifier of the user in Incode system. |
| `verification_trace_id` | `string` | Trace ID for tracking the verification process and fetching detailed result. |
| `user_name` | `string` | Name of the user as in the directory for whom the verification has been requested. |
| `user_id` | `string` | User id of the user as in the directory for whom the verification has been requested. |
| `workforce_user_type` | `string` | The value tells whether the verification was request for an `EMPLOYEE` or a `CANDIDATE`. |
| `ip` | `string` | IP address of a mobile device where verification was performed in IPv4 format. |
| `latitude` | `number` | IP geolocation latitude in decimal degrees. |
| `longitude` | `number` | IP geolocation longitude in decimal degrees. |

### Webhook: Verification Started

| **Field** | **Type** | **Description** |
| --- | --- | --- |
| `integration_id` | `string` | Identifier for the integration for which verification has been requested. |
| `verification_trace_id` | `string` | Trace ID for tracking the verification process. |
| `user_name` | `string` | Name of the user as in the directory for whom the verification has been requested. |
| `user_id` | `string` | User id of the user as in the directory for whom the verification has been requested. |
| `workforce_user_type` | `string` | The value tells whether the verification was request for an `EMPLOYEE` or a `CANDIDATE`. |
| `ip` | `string` | IP address of a mobile device where verification was performed in IPv4 format. |
| `latitude` | `number` | IP geolocation latitude in decimal degrees. |
| `longitude` | `number` | IP geolocation longitude in decimal degrees. |

### Webhook: Verification Succeeded

| **Field** | **Type** | **Description** |
| --- | --- | --- |
| `integration_id` | `string` | Identifier for the integration for which verification has been requested. |
| `verification_trace_id` | `string` | Trace ID for tracking the verification process. |
| `verification_id` | `string` | ID of the verification tied to the data snapshot. This value is used in the fetch verification result endpoint. |
| `identity_id` | `string` | Unique identifier of the user. |
| `user_name` | `string` | Name of the user as in the directory for whom the verification has been requested. |
| `user_id` | `string` | User id of the user as in the directory for whom the verification has been requested. |
| `enrollment_type` | `string` | In case this is a new user, the value will be `ENROLLMENT`; In case that this user is already enrolled, the value will be `RETURNING`. |
| `workforce_user_type` | `string` | The value tells whether the verification was request for an `EMPLOYEE` or a `CANDIDATE`. |
| `ip` | `string` | IP address of a mobile device where verification was performed in IPv4 format. |
| `latitude` | `number` | IP geolocation latitude in decimal degrees. |
| `longitude` | `number` | IP geolocation longitude in decimal degrees. |

### Webhook: Verification Failed

| **Field** | **Type** | **Description** |
| --- | --- | --- |
| `integration_id` | `string` | Identifier for the integration for which verification has been requested. |
| `verification_trace_id` | `string` | Trace ID for tracking the verification process. |
| `failure_reason` | `string` | Reason for the verification failure (e.g., `FACE_MATCH_FAILED`). |
| `user_name` | `string` | Name of the user as in the directory for whom the verification has been requested. |
| `user_id` | `string` | User id of the user as in the directory for whom the verification has been requested. |
| `enrollment_type` | `string` | In case this is a new user, the value will be `ENROLLMENT`; In case that this user is already enrolled, the value will be `RETURNING`. |
| `workforce_user_type` | `string` | The value tells whether the verification was request for an `EMPLOYEE` or a `CANDIDATE`. |
| `ip` | `string` | IP address of a mobile device where verification was performed in IPv4 format. |
| `latitude` | `number` | IP geolocation latitude in decimal degrees. |
| `longitude` | `number` | IP geolocation longitude in decimal degrees. |

**Failure Reasons Details:**

| **Enum** | **Description** |
| --- | --- |
| `FACE_MATCH_FAILED` | Selfie does not match the face image from the ID. |
| `ID_VALIDATION_FAILED` | ID document could not be validated. |
| `DATA_SHARING_CONSENT_DECLINED` | User declined to share data with the customer. |
| `VERIFICATION_EXPIRED` | Verification request expired before completion. |
| `NAME_DOES_NOT_MATCH` | Name on the ID does not match the name in the employee directory. |
| `EMPLOYEE_DOES_NOT_EXIST` | No employee record exists for the provided identifier. |
| `UNDER_REVIEW` | User’s documents are under manual review. |

### Webhook: Data Sharing Consent Revoked

| **Field** | **Type** | **Description** |
| --- | --- | --- |
| `identity_id` | `string` | Unique identifier of the user who deleted the identity or revoked data sharing consent. |
| `user_name` | `string` | Name of the user as in the directory who performed this action. |
| `user_id` | `string` | User id of the user as in the directory who performed this action. |
| `workforce_user_type` | `string` | The value tells whether the this user is an `EMPLOYEE` or a `CANDIDATE` in your organization. |
| `ip` | `string` | IP address of a mobile device where the action was performed in IPv4 format. |
| `latitude` | `number` | IP geolocation latitude in decimal degrees. |
| `longitude` | `number` | IP geolocation longitude in decimal degrees. |

# Error Handling and Retry Policy

Webhooks use an **exponential backoff retry policy**, making up to **5 attempts** to deliver a notification in case of endpoint failures. Ensure your endpoint is ready to handle retries and process duplicate notifications gracefully.

Webhook retries will be triggered in the following scenarios:

- Timeout when calling the registered endpoint.
- The returned status code from registered endpoint is not `200 OK` along with the application/json header or the status code `204 No content`.

The retry policy for webhooks is exponential with an initial interval of 30s, multiplier of 2.5, and max attempts of 5:

| Retry attempt | Delay (seconds) | Delay (minutes) | Total (minutes) |
| --- | --- | --- | --- |
| 1 | 30 | 0.5 | 0.5 |
| 2 | 75 | 1.25 | 1.75 |
| 3 | 187.5 | 3.13 | 4.88 |
| 4 | 468.75 | 7.81 | 12.69 |
| 5 | 1 171.88 | 19.53 | 32.22 |

This means the maximum time a webhook can take to reach its destination is approximately 32 minutes.

## Allowlist webhook source IPs

SAAS (production): IP 18.210.119.234

DEMO (development) IP 34.198.171.165

For further assistance with webhook setup or troubleshooting, contact [Support](mailto:support@incode.com).
