Skip to content

Webhooks

Webhooks send notifications about session progress to a client system endpoint. They let you respond when a Workflow ends without continuously polling the API.

A webhook is a server-to-server request. Use it as the primary signal for updating the state of an application, then request the current session result if necessary.

Configuration

In the dashboard, open the settings for the required Workflow and add the recipient URL under Webhooks. You can configure up to five URLs for one Workflow, change or delete existing URLs, and send a test event.

The endpoint must be available over HTTPS and accept POST requests with a JSON body.

Event types

Event When it is sent data contents
flow.start The user started the session List of Workflow technologies
flow.end The session ended Final session result
technology.start A technology started Technology code and name
technology.end A technology ended Result of the corresponding technology

Common structure

Each event contains a common envelope:

Field Type Description
id string Unique event identifier
event string Event type
session_id string Workflow session identifier
created number Event creation time as a Unix timestamp
success boolean Whether the event was successful
flow_name string Workflow name
metadata object \| null Metadata passed when the session was created
data object Data specific to the event type

flow.start

This event reports that the user started the Workflow:

{
  "id": "d45aef15-8949-4812-b873-650615d51d1a",
  "event": "flow.start",
  "session_id": "70f5e424-07a9-4393-ba31-7f3de8681a72",
  "created": 1734597331,
  "success": true,
  "flow_name": "Liveness Head Position Flow",
  "metadata": {},
  "data": {
    "technologies": ["LDHP"]
  }
}

flow.end

The flow.end event reports that the session has ended and includes the result in data.session_result.

Successful completion:

{
  "id": "5665f3c1-adce-4fe7-85f3-1e40e38cc0b7",
  "event": "flow.end",
  "session_id": "70f5e424-07a9-4393-ba31-7f3de8681a72",
  "created": 1734597391,
  "success": true,
  "flow_name": "Liveness Head Position Flow",
  "metadata": {},
  "data": {
    "session_result": {
      "status": "FINISHED",
      "session_id": "70f5e424-07a9-4393-ba31-7f3de8681a72",
      "technologies": [
        {
          "code": "LDHP",
          "name": "Liveness Head Position",
          "description": "Detect liveness by photo and head position"
        }
      ],
      "liveness_result": {
        "result": true,
        "eye_closed": false,
        "prediction": "0.9980",
        "face_center": true,
        "face_direction": "forward"
      },
      "flow_session_result": true
    }
  }
}

Unsuccessful completion:

{
  "id": "2d891060-3b14-4920-ad0f-d21b70a9c33c",
  "event": "flow.end",
  "session_id": "3efb1a25-5d94-493d-99cf-043881909820",
  "created": 1734597876,
  "success": false,
  "flow_name": "Liveness Head Position Flow",
  "metadata": {},
  "data": {
    "session_result": {
      "status": "FAILED",
      "session_id": "3efb1a25-5d94-493d-99cf-043881909820",
      "technologies": [
        {
          "code": "LDHP",
          "name": "Liveness Head Position",
          "description": "Detect liveness by photo and head position"
        }
      ],
      "liveness_result": {
        "result": false,
        "failure_reason": {
          "type": "CALC_RESULT",
          "detail": "Low overall prediction"
        }
      },
      "flow_session_result": false
    }
  }
}

The possible failure_reason values are listed in the failure reasons reference.

Technology events

technology.start contains the code and name of the technology that started:

{
  "id": "8c44f37b-6040-40ed-b391-682a3b29dc2b",
  "event": "technology.start",
  "session_id": "70f5e424-07a9-4393-ba31-7f3de8681a72",
  "created": 1734597343,
  "success": true,
  "flow_name": "Liveness Head Position Flow",
  "metadata": {},
  "data": {
    "technology_code": "LDHP",
    "technology_name": "Liveness Head Position"
  }
}

technology.end contains the result block for the technology that ended:

{
  "id": "35bef608-a327-4b46-a4e0-cf1a8c6e0703",
  "event": "technology.end",
  "session_id": "70f5e424-07a9-4393-ba31-7f3de8681a72",
  "created": 1734597388,
  "success": true,
  "flow_name": "Liveness Head Position Flow",
  "metadata": {},
  "data": {
    "liveness_result": {
      "result": true,
      "eye_closed": false,
      "prediction": "0.9980",
      "face_center": true,
      "face_direction": "forward",
      "failure_reason": null
    }
  }
}

The block name and its fields depend on the technology. Common result blocks are listed on the retrieving results page.

Test the endpoint with cURL

The following request simulates event delivery to your endpoint:

curl --request POST \
  --url 'https://example.com/webhooks/biometric' \
  --header 'Content-Type: application/json' \
  --data '{
    "id": "d45aef15-8949-4812-b873-650615d51d1a",
    "event": "flow.start",
    "session_id": "70f5e424-07a9-4393-ba31-7f3de8681a72",
    "created": 1734597331,
    "success": true,
    "flow_name": "Liveness Head Position Flow",
    "metadata": {},
    "data": {
      "technologies": ["LDHP"]
    }
  }'

Reliable processing

  • Return a successful 2xx response after the event has been stored reliably.
  • Process events idempotently: redelivery of the same id must not repeat a business operation.
  • Associate the event with your application by session_id.
  • Do not rely on the order in which separate HTTP requests arrive.
  • If processing takes a long time, store the event and continue asynchronously after responding.
  • Use flow.end as the completion signal, and retrieve the current state through the results API when necessary.