Session Webhooks
Overview of the Session Started, Session Failed, Session Succeeded, and Session Pending Review webhooks
Session webhooks let you set up notifications for events that happen during any session triggered by a Flow or Workflow. You can configure them, along with other types of webhooks, in Dashboard.
Learn more about webhooks
Webhooks are event notifications. They let your organization's application know when a specific event happens on the Incode platform or when a process initiated by a user is completed (also known as a callback). Your application can then take action based on the notification.
Webhooks are asynchronous (that is, the communication is only from the Incode platform to your application). You must configure them if you want to use them.
Each session webhook notifies you about a specific session event. This is different from the Onboarding Status webhook, which sends notifications at the completion of every module during a single session. Depending on the number of modules in the session Flow or Workflow, this could be more notifications than you need or want.
Session webhooks provide additional flexibility and let you tailor your notifications for specific needs.
There are six session webhooks available:
- Session Started: Triggered when any session triggered by a Flow or Workflow starts.
- Session Progress: Triggered when an existing session link is resumed (not on initial session creation).
- Session Failed: Triggered when any session triggered by a Flow or Workflow fails. Sessions can fail at various points and for various reasons during a Flow or Workflow. You can view more information about failed sessions in Dashboard. Go to Dashboard > Sessions and click any session in the table to open it.
- Session Succeeded: Triggered when any session triggered by a Flow or Workflow succeeds.
- Session Pending Review: Triggered when any session triggered by a Flow or Workflow requires manual review.
- Identity Enrolled: Triggered the first time an Identity is created. Updates to an existing Identity do not emit this event.
Key facts about session webhooks
- Each session webhook notification contains a number of common fields. These provide context and allow you to track what's happening more easily.
- Notifications come as
POSTrequests to the endpoint you configured in Dashboard. - Notification headers are passed as key/value pairs.
- Notification payloads are sent in JSON format. You must configure any internal settings to include
Accept Application/json. - Data is included in the first notification for which it is available.
Notification payload fields
Common fields
The fields in the following table are common to all session webhook notifications (SESSION_STARTED, SESSION_PROGRESS, SESSION_FAILED, SESSION_SUCCEEDED, and SESSION_PENDING_REVIEW). They are the only fields included in SESSION_STARTED and SESSION_PROGRESS.
| Field | Type | Description |
|---|---|---|
event_type | string | Name of the webhook providing the notification: SESSION_STARTED, SESSION_PROGRESS, SESSION_FAILED, SESSION_SUCCEEDED, or SESSION_PENDING_REVIEW |
timestamp | string | UTC timestamp of the triggering event in ISO 8601 format |
interviewId | string | Unique identifier for the session |
externalCustomerId | string | Unique identifier from your system that is used for data matching |
clientId | string | Unique identifier assigned to your organization |
configurationId | string | Unique identifier assigned to the Flow or Workflow for this session |
integrationId | string | Unique identifier assigned by Incode to the integration associated with this session. If there was no integration for the session, this field does not appear. |
integrationType | string | Type of integration associated with this session. null if no integration reference is present or cannot be resolved. |
loginHint | string | Displays a value entered by the end user as a login hint for this session. If no login hint was used, this field does not appear. |
devices | array | Always null for SESSION_STARTED and SESSION_PROGRESS. See Devices array for details. |
Fields available after a session starts
The next table explains fields that are only available after a session starts. These fields are included in SESSION_FAILED, SESSION_SUCCEEDED, or SESSION_PENDING_REVIEW notifications.
| Field | Type | Description |
|---|---|---|
onboardingStatus | string | Status of the session; the value is always ONBOARDING_FINISHED. The term "onboarding" here applies to any session. |
ip | string | IP address for the end user device (legacy field, preserved for backward compatibility). Not available for fully API-integrated sessions. |
latitude | string | Latitude at which the end user device was located during the session (legacy field, preserved for backward compatibility). Not available for fully API-integrated sessions. |
longitude | string | Longitude at which the end user device was located during the session (legacy field, preserved for backward compatibility). Not available for fully API-integrated sessions. |
devices | array | Structured array of device objects containing enriched device fingerprint data. Empty array ([]) when no device data is available. See Devices array. |
Fields available for specific event types
The following table explains fields that appear only in specific event type notifications.
| Field | Event type(s) | Type | Description |
|---|---|---|---|
identityId | SESSION_SUCCEEDED, SESSION_FAILED | string | Unique identifier for the Identity that was matched or created for this session. Included in SESSION_FAILED when the failed session is tied to an existing Identity. |
failureReasons | SESSION_FAILED | array | Sorted, deduplicated array of upper-snake-case string identifiers indicating why the session failed. Replaces the legacy failureReason field. See Failure reasons. |
Devices array
The devices field is a structured array of device objects included in SESSION_FAILED, SESSION_SUCCEEDED, and SESSION_PENDING_REVIEW notifications. It replaces the flat ip, latitude, and longitude fields previously included. However, these fields are preserved for backward compatibility. Devices are sorted by timestamp, with the oldest first.
Each device object contains the following fields:
| Field | Type | Description |
|---|---|---|
ip | string | IP address of the end user device |
latitude | number | Latitude of the end user device location |
longitude | number | Longitude of the end user device location |
browser | string | Browser used during the session |
deviceModel | string | Model of the end user device |
deviceType | string | Type of device (for example, mobile) |
osVersion | string | Operating system and version |
hash | string | Device fingerprint hash |
Example:
{
"ip": "203.0.113.10",
"latitude": 37.7749,
"longitude": -122.4194,
"browser": "Chrome",
"deviceModel": "iPhone 15",
"deviceType": "mobile",
"osVersion": "iOS 17.5",
"hash": "fingerprint-hash"
}Failure reasons
Breaking change: The legacyfailureReason(singular string) field has been removed fromSESSION_FAILEDnotifications and replaced by thefailureReasonsarray.
The failureReasons field is included only in SESSION_FAILED notifications. It contains a stable, sorted, deduplicated array of identifiers indicating why the session failed.
Example:
{
"event_type": "SESSION_FAILED",
"failureReasons": ["ID_VALIDATION", "LIVENESS"]
}The following table lists all possible identifiers:
| Identifier | Source |
|---|---|
AUTHENTICATION | authentication score field |
ID_VALIDATION | idValidation score field |
SECOND_ID_VALIDATION | secondIdValidation score field |
ANTIFRAUD | antifraud score field |
LIVENESS | liveness score field |
DEEPSIGHT | deepsight score field |
FACE_CAPTURE_ASSESSMENT | faceCaptureAssessment score field |
FACE_RECOGNITION | faceRecognition score field |
FACE_RECOGNITION_SECOND_ID | faceRecognitionSecondId score field |
GOVERNMENT_VALIDATION | governmentValidation score field |
VIDEO_SELFIE | videoConference score field |
PREMIUM_EXTERNAL_VERIFICATION | premiumExternalVerification score field |
CURP_VERIFICATION | curpVerification score field |
ID_OCR_CONFIDENCE | idOcrConfidence score field |
ID_OCR_CONFIDENCE_SECOND_ID | idOcrConfidenceSecondId score field |
INCODE_WATCHLIST | incodeWatchlistScore score field |
DEVICE_RISK | deviceRisk score field |
BEHAVIORAL_RISK | behavioralRisk score field |
TRUST_GRAPH | trustGraph score field |
AUTOPILOT | autopilot score field |
INVOICE_VALIDATION | invoiceValidation score field |
LINK_EXPIRED | Session link expiry failure path |
MANUAL_REJECTED | Final result is MANUAL_FAIL |
OTHER | Overall failure with no mapped module reason |
Identity Enrolled webhook
The IDENTITY_ENROLLED webhook fires the first time an Identity is created. It does not fire for updates to an existing Identity.
The payload for IDENTITY_ENROLLED uses the following shape:
| Field | Type | Description |
|---|---|---|
eventType | string | Always IDENTITY_ENROLLED |
timestamp | string | UTC timestamp of the triggering event in ISO 8601 format |
identityId | string | Unique identifier for the newly created Identity (required) |
interviewId | string | Unique identifier for the session associated with the Identity creation |
externalId | string | External identifier, if available; null if not |
externalCustomerId | string | Unique identifier from your system used for data matching; null if not available |
clientId | string | Unique identifier assigned to your organization |
configurationId | string | Unique identifier assigned to the Flow or Workflow for this session |
integrationReference | string | Reference to the integration associated with this session; null if not available |
loginHint | string | Login hint provided by the end user; null if not used |
Example payload:
{
"eventType": "IDENTITY_ENROLLED",
"timestamp": "2026-05-20T14:00:00Z",
"identityId": "65f8...",
"interviewId": "65f7...",
"externalId": "ext-abc-123",
"externalCustomerId": "cust-456",
"clientId": "client-xyz",
"configurationId": "flow-prod-onboarding",
"integrationReference": "ref-789",
"loginHint": null
}Session Failed on link expiration
When a Workforce verification link expires, the platform sends a SESSION_FAILED webhook with failureReasons containing ["LINK_EXPIRED"]. This feature is configuration-dependent. Contact your Incode representative to enable it.
Error handling and retry policy
Webhooks make up to 5 attempts to deliver a notification in case of endpoint failures. You should ensure your endpoint is ready to handle retries and process duplicate notifications gracefully.
Retries will be triggered by either of these scenarios:
- A timeout is received when your endpoint is called
- A status code is returned from your service and is not either:
200 OKalong with theapplication/jsonheader, or204 No content
The retry policy for webhooks is exponential, with an initial interval of 30 seconds and a multiplier of 2.5. The maximum number of attempts is 5. This means the maximum time a webhook can take to reach its destination is approximately 32 minutes, as illustrated in the following table.
| 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 |
Webhook IP address list
If your organization restricts inbound traffic for your network, make sure the following IP addresses are added to your allow list.
United States
Allow the IP addresses shown in this table for the SAAS (Production) environment.
| IP Address | Active |
|---|---|
| 54.86.34.156 | Currently Active |
| 3.142.125.52 | Currently Active |
| 54.85.117.182 | As of February 2, 2026 |
| 3.233.40.153 | As of February 2, 2026 |
Allow this IP address for the Demo environment.
| IP Address | Active |
|---|---|
| 34.198.171.165 | Active since October 2024 (previously 18.210.119.234) |
Europe
Allow this IP address for both the Production and Demo environments.
| IP Address | Active |
|---|---|
| 18.158.116.18 | Active |
