Skip to content

API Usage Guide

The IDLive® eKYC Toolkit provides a set of flexible API methods that support the implementation of key scenarios in eKYC systems.

Below is a detailed description of all methods, including their purpose, parameters, and expected responses.

You can also use the OpenAPI Specification available at http://host:port/v3/api-docs to explore the API or generate client libraries.

Tools like Postman or Swagger UI can be used to interact with the API; Swagger UI is accessible at http://host:port/swagger-ui/index.html.

Identity Check

POST /check

The POST /check endpoint is a core part of the IDLive® eKYC Toolkit.
It performs identity verification by analyzing a user's selfie and a photograph of their identity document.

Depending on the parameters specified in the request, this method can perform a combination of the following checks:

  • Face Presentation Attack Detection: Validates that the selfie was captured from a live person, detecting fraudulent attempts such as printed photos or screen replays.
  • Document Presentation Attack Detection: Ensures that the document image was captured from a genuine physical document and not a reproduction or display.
  • Deepfake Detection: Detects AI-generated synthetic faces in selfie images that attempt to impersonate a real person.
  • Injection Attack Detection: Ensures that the image was captured securely and not tampered with.
  • Face Matching: Compares the face in the selfie with the face on the identity document to confirm that both belong to the same person.
  • Face Search: Searches the faces from the selfie and the document in a database to detect duplicates.

Query Parameters

Name Type Required Default Description
encrypted boolean No true Should be set to true if payload is encrypted, false if not.

Request Body

Content-Type: multipart/form-data

Form Fields

Parameter Type Required Description
checkModel JSON Yes Configuration object specifying which checks to run.
face binary No Face image payload.
doc binary No Document image payload.

{
  "operations": ["FACE_CHECK", "DOC_CHECK", "FACE_MATCH_VALIDATION", "FACE_MATCH_SEARCH"],
  "face_check_parameters": {
    "domain": "GENERAL",
    "pipelines": [
      {"type": "PRESENTATION_ATTACK"},
      {"type": "DEEPFAKE_ATTACK"},
      {"type": "INJECTION_ATTACK"}
    ]
  },
  "document_check_parameters": {
    "pipelines": [
      {"type": "SCREEN_REPLAY_ATTACK"},
      {"type": "PRINTED_COPY_ATTACK"},
      {"type": "PORTRAIT_SUBSTITUTION_ATTACK"}
    ]
  },
  "face_search_parameters": {
    "collections": ["default-collection"],
    "limit": 5,
    "max_faces": 1
  }
}
Field Type Required Description
operations string[] Yes List of checks to perform. Possible values:
FACE_CHECK,
DOC_CHECK,
FACE_MATCH_VALIDATION,
FACE_MATCH_SEARCH.
face_check_parameters object No Settings for face checks.
document_check_parameters object No Settings for document checks.
face_search_parameters object No Settings for face search.

[
"FACE_CHECK",
"DOC_CHECK",
"FACE_MATCH_VALIDATION",
"FACE_MATCH_SEARCH"
]
Operation Description
FACE_CHECK Performs analysis of the selfie image, including Presentation Attack, Deepfake, and Injection detection.
DOC_CHECK Performs analysis of the document photo to detect Screen Replay, Printed Copy, Portrait Substitution, and Digital Manipulation Attacks.
FACE_MATCH_VALIDATION Compares the face from the selfie to the face on the document.
FACE_MATCH_SEARCH Searches the faces from the selfie and the document in a database to detect duplicates.

{
  "domain": "GENERAL",
  "pipelines": [
    {
      "type": "PRESENTATION_ATTACK",
      "pipeline": "optional_pipeline_id",
      "calibration": "REGULAR"
    }
  ]
}
Field Type Required Description
domain string No Domain for face checks. Possible values:
GENERAL,
DESKTOP.
pipelines object[] No List of face checks to perform. Each item is an object described below.
type string Yes Type of check to perform. Supported values:
PRESENTATION_ATTACK,
DEEPFAKE_ATTACK,
INJECTION_ATTACK.
pipeline string No Pipeline name to use for the check. If not set, default pipeline is used.
calibration string No Adjusting a system's balance between false acceptance and false rejection rates. Possible values:
REGULAR (default),
SOFT,
HARD.

{
  "pipelines": [
    {
      "type": "SCREEN_REPLAY_ATTACK",
      "pipeline": "optional_pipeline_id",
      "calibration": "REGULAR"
    }
  ]
}
Field Type Required Description
pipelines object[] No List of document checks to perform. Each item is an object described below.
type string Yes Type of check to perform. Supported values:
SCREEN_REPLAY_ATTACK,
PRINTED_COPY_ATTACK,
PORTRAIT_SUBSTITUTION_ATTACK,
DIGITAL_MANIPULATION_ATTACK.
pipeline string No Pipeline name to use for the check. If not set, default pipeline is used.
calibration string No Adjusting a system's balance between false acceptance and false rejection rates. Possible values:
REGULAR (default),
SOFT,
HARD.

{
  "collections": ["default-collection"],
  "limit": 5,
  "max_faces": 1
}
Field Type Required Description
collections string[] Yes List of collection names to search in.
limit integer No Number of matching results to return. Default is 5.
max_faces integer No Maximum allowed number of faces in the image. If more faces are detected, an error will be returned. Default is 1.

Response: 200 OK

Returns a JSON object with result sections corresponding to the requested operations in checkModel.operations. Each section reflects the outcome of a specific check and includes either a success result or an error description.

{
  "face_result": { ... },
  "doc_result": { ... },
  "face_validation_result": { ... },
  "face_search_result": { ... }
}

Each section is described in detail in the sections below: face_result, doc_result, face_validation_result, face_search_result.

face_result

Returned when FACE_CHECK is requested. Contains a results array, where each entry corresponds to a specific check. The fields of each check are described below.

{
  "results": [
    {
      "type": "PRESENTATION_ATTACK",
      "pipeline": "pad-r-1",
      "calibration": "REGULAR",
      "probability": 0.95255303,
      "quality": 0.9972526,
      "status_code": "OK"
    },
    {
      "type": "DEEPFAKE_ATTACK",
      "pipeline": "dfd-1",
      "calibration": "REGULAR",
      "probability": 0.9324415,
      "quality": 0.9972526,
      "status_code": "OK"
    },
    {
      "type": "INJECTION_ATTACK",
      "probability": 1.0,
      "status_code": "OK"
    }
  ]
}
{
  "results": [
    {
      "type": "PRESENTATION_ATTACK",
      "pipeline": "pad-r-1",
      "calibration": "REGULAR",
      "error": "Failed to detect face",
      "status_code": "FACE_NOT_FOUND"
    },
    {
      "type": "DEEPFAKE_ATTACK",
      "pipeline": "dfd-1",
      "calibration": "REGULAR",
      "error": "Failed to detect face",
      "status_code": "FACE_NOT_FOUND"
    },
    {
      "type": "INJECTION_ATTACK",
      "error": "Bad Request",
      "status_code": "FACE_NOT_FOUND"
    }
  ]
}
Field Type Description
type string Check type. Supported values: PRESENTATION_ATTACK, DEEPFAKE_ATTACK, INJECTION_ATTACK.
pipeline string Pipeline name used for the check.
calibration string Calibration used. Supported values: REGULAR, SOFT, HARD.
probability number It ranges from 0 (spoofed) to 1 (live). Threshold: 0.5.
quality number Deprecated.
status_code string Code indicating the result of the check. See explanation below.

status_code indicates the result of the check. Possible values:

  • OK – the check was successfully completed and a probability value was returned.
  • ERROR – an internal error occurred during the check.
  • Validation error codes (e.g., FACE_NOT_FOUND, FACE_TOO_SMALL, etc.) – indicate why the image was rejected. You can find the complete list here.

doc_result

Returned when DOC_CHECK is requested. Contains a results array, where each entry corresponds to a specific check. The fields of each check are described below.

{
  "results": [
    {
      "type": "SCREEN_REPLAY_ATTACK",
      "pipeline": "default-sr",
      "calibration": "REGULAR",
      "probability": 0.0,
      "quality_warnings": [],
      "status_code": "OK"
    },
    {
      "type": "PORTRAIT_SUBSTITUTION_ATTACK",
      "pipeline": "default-ps",
      "calibration": "REGULAR",
      "probability": 0.830956,
      "quality_warnings": [],
      "status_code": "OK"
    },
    {
      "type": "PRINTED_COPY_ATTACK",
      "pipeline": "default-pc",
      "calibration": "REGULAR",
      "probability": 0.0,
      "quality_warnings": [],
      "status_code": "OK"
    },
    {
      "type": "DIGITAL_MANIPULATION_ATTACK",
      "pipeline": "default-dm",
      "calibration": "REGULAR",
      "probability": 0.1597147,
      "quality_warnings": [],
      "status_code": "OK"
    }
  ]
}
{
  "results": [
    {
      "type": "SCREEN_REPLAY_ATTACK",
      "pipeline": "default-sr",
      "calibration": "REGULAR",
      "status_code": "DOCUMENT_NOT_FOUND"
    },
    {
      "type": "PORTRAIT_SUBSTITUTION_ATTACK",
      "pipeline": "default-ps",
      "calibration": "REGULAR",
      "status_code": "DOCUMENT_NOT_FOUND"
    },
    {
      "type": "PRINTED_COPY_ATTACK",
      "pipeline": "default-pc",
      "calibration": "REGULAR",
      "status_code": "DOCUMENT_CROPPED"
    },
    {
      "type": "DIGITAL_MANIPULATION_ATTACK",
      "pipeline": "default-dm",
      "calibration": "REGULAR",
      "status_code": "DOCUMENT_NOT_FOUND"
    }
  ]
}
Field Type Description
type string Check type. Supported values:
SCREEN_REPLAY_ATTACK,
PRINTED_COPY_ATTACK,
PORTRAIT_SUBSTITUTION_ATTACK,
DIGITAL_MANIPULATION_ATTACK.
pipeline string Pipeline name used for the check.
calibration string Calibration used. Supported values: REGULAR, SOFT, HARD.
probability number It ranges from 0 (spoofed) to 1 (live). Threshold: 0.5.
quality_warnings string[] Image quality warnings.
status_code string Code indicating the result of the check. See explanation below.

status_code indicates the result of the check. Possible values:

  • OK – the check was successfully completed and a probability value was returned.
  • ERROR – an internal error occurred during the check.
  • Validation error codes (DOCUMENT_NOT_FOUND, DOCUMENT_PHOTO_NOT_FOUND, DOCUMENT_CROPPED) – indicate why the image was rejected. You can find the complete list here.

face_validation_result

Returned when FACE_MATCH_VALIDATION is requested. Contains the result of comparing the face in the selfie with the face on the identity document. The fields of the result are described below.

{
  "probability": 0.0048826,
  "status_code": "OK"
}
{
  "error": "Failed to detect face",
  "status_code": "ERROR"
}
Field Type Description
probability number It ranges from 0 (different identities) to 1 (same identity). Threshold: 0.5.
error string Error description.
status_code string Code indicating the result of the face validation. See explanation below.

status_code indicates the result of the check. Possible values:

  • OK – the validation was successfully completed and a probability value was returned.
  • ERROR – an internal error occurred during the check.

face_search_result

Returned when FACE_MATCH_SEARCH is requested. Contains a results array, where each entry represents a search performed using a specific face source (FACE or DOCUMENT). Each entry refers to the target collection and may contain a list of matched records with their probability scores, the image source, and the status of the search. The fields of each search result are described below.

{
  "results": [
    {
      "collection": "ekyc",
      "results": [
        {
          "record_id": "16d33ecb-da91-4f39-afe5-46a8c846e40e",
          "probability": 0.99999964
        },
        {
          "record_id": "1395c0d0-186b-493e-87b1-cfcad9b42e83",
          "probability": 0.56999912
        }
      ],
      "image_source": "FACE",
      "status_code": "OK"
    },
    {
      "collection": "ekyc",
      "results": [
        {
          "record_id": "86094151-2e46-421e-969c-07bae1924c0b",
          "probability": 0.9748826463
        },
        {
          "record_id": "69be6f40-123b-459f-8230-893aa74230f8",
          "probability": 0.0048826463
        }
      ],
      "image_source": "DOCUMENT",
      "status_code": "OK"
    }
  ]
}
{
  "results": [
    {
      "collection": "ekyc",
      "error": "Collection does not exist",
      "image_source": "FACE",
      "status_code": "ERROR"
    },
    {
      "collection": "ekyc",
      "error": "Collection does not exist",
      "image_source": "DOCUMENT",
      "status_code": "ERROR"
    }
  ]
}
Field Type Description
collection string Name of the collection used for the search.
image_source string Source of the face used for the search. Possible values: FACE (from selfie) or DOCUMENT (from ID photo).
error string Error description.
status_code string Code indicating the result of the face search. See explanation below.
results object[] List of matched results, each with a record_id and probability.
record_id string Identifier of the matched record in the collection.
probability number It ranges from 0 (different identities) to 1 (same identity). Threshold: 0.9.

status_code indicates the result of the search. Possible values:

  • OK – the search was successfully completed.
  • ERROR – an internal error occurred during the check.

Response: 400 Bad Request

Returned if request structure is invalid or a processing error occurs.

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X 'POST' \
  'http://localhost:8080/check' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'checkModel={"operations":["FACE_CHECK","DOC_CHECK","FACE_MATCH_VALIDATION"]};type=application/json' \
  -F 'face=@/path/to/face-encrypted-data' \
  -F 'doc=@/path/to/doc-encrypted-data'
import requests, json

headers = {
    'Accept': 'application/json'
}
check_model = {
    'operations': ['FACE_CHECK', 'DOC_CHECK', 'FACE_MATCH_VALIDATION']
}
with open('/path/to/face-encrypted-data', 'rb') as face_file, \
     open('/path/to/doc-encrypted-data', 'rb') as doc_file:

    files = {
        'checkModel': ('checkModel', json.dumps(check_model), 'application/json'),
        'face': ('face', face_file, 'application/octet-stream'),
        'doc': ('doc', doc_file, 'application/octet-stream')
    }

    response = requests.post(
        'http://localhost:8080/check',
        headers=headers,
        files=files
    )

Collections

Create Collection

POST /collections

Creates a new biometric collection.

Query Parameters

Name Type Required Description
collection string Yes Name of the collection.

Response: 201 OK

Collection was created successfully.

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X POST "http://localhost:8080/collections?collection=collection-name"
import requests

params = {
    'collection': collection_name
}
response = requests.post(
    'http://localhost:8080/collections',
    params=params
)

Delete Collection

DELETE /collections

Removes a biometric collection.

Query Parameters

Name Type Required Description
collection string Yes Name of the collection to remove.
force boolean No If true, forcibly deletes the collection.

Response: 204 No Content
Collection removed successfully.

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X DELETE "http://localhost:8080/collections?collection=collection-name&force=true"
import requests

params = {
    'collection': collection_name,
    'force': True
}
response = requests.delete(
    'http://localhost:8080/collections',
    params=params
)

Remove Record From Collection

DELETE /collections/remove-record

Removes a specific record from a collection.

Query Parameters

Name Type Required Description
collection string Yes Collection name.
recordId string Yes Record ID to remove.

Response: 204 No Content
Record removed successfully.

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X DELETE "http://localhost:8080/collections/remove-record?collection=collection-name&recordId=record-id"
import requests

params = {
    'collection': collection_name,
    'recordId': record_id
}
response = requests.delete(
    'http://localhost:8080/collections/remove-record',
    params=params
)

Face Matching

Generate Template

POST /generate-template

Generates a biometric matching template from a single image.

Query Parameters

Name Type Required Description
encrypted boolean Yes Should be set to true if payload is encrypted, false if not.

Request Body
Content-Type: application/octet-stream
Binary payload (image data).

Response: 201 OK

{
  "template": "base64-encoded-template-string"
}

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X POST "http://localhost:8080/generate-template?encrypted=true" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@/path/to/encrypted-image"
import requests

headers = {
    'Content-Type': 'application/octet-stream'
}
params = {
    'encrypted': True
}
with open('/path/to/encrypted-image', 'rb') as image:

    response = requests.post(
    'http://localhost:8080/generate-template',
    headers=headers,
    params=params,
    data=image
    )

Match Over Template

POST /match-over-template

Compares a face image against a previously generated biometric template.

Query Parameters

Name Type Required Description
encrypted boolean Yes Should be set to true if the payload is encrypted.

Request Body
Content-Type: multipart/form-data

Field Type Required Description
file binary Yes Face image to match.
template string Yes Base64-encoded template to compare to.

Response: 200 OK

{
  "score": 0.85
}

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X POST "http://localhost:8080/match-over-template?encrypted=true" \
  -F "file=@/path/to/encrypted-image" \
  -F "template=<BASE64_TEMPLATE>"
import requests

files = {
    'file': ('file', open('/path/to/encrypted-image', 'rb'), 'application/octet-stream'),
    'template': ('template', <BASE64_TEMPLATE>, 'application/octet-stream')
}
params = {
    'encrypted': True
}
response = requests.post(
    'http://localhost:8080/match-over-template',
    files=files,
    params=params
)

Add Template to Collection

POST /add-template

Adds one or more templates to a collection in the biometric database.

Query Parameters

Name Type Required Description
collection string Yes Target collection name (must already exist).

Request Body
Content-Type: application/json

{
  "templates": ["base64-template-1", "base64-template-2"]
}

Response: 201 OK

{
  "record_ids": ["generated-record-id-1", "generated-record-id-2"]
}

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X POST "http://localhost:8080/add-template?collection=default" \
  -H "Content-Type: application/json" \
  -d '{"templates":["<BASE64_TEMPLATE>"]}'
import requests

params = {
    'collection': collection_name
}
data = {
    'templates': ["<BASE64_TEMPLATE>"]
}
response = requests.post(
    'http://localhost:8080/add-template',
    params=params,
    json=data
)

Add Image to Collection

POST /add-image

Generates templates from an image and stores them in the target collection.

Query Parameters

Name Type Required Description
collection string Yes Target collection name (must already exist).
maxFaces integer No Maximum allowed number of faces in the image. If more faces are detected, an error will be returned. Default is 1.
encrypted boolean Yes Should be set to true if the payload is encrypted.

Request Body
Content-Type: application/octet-stream
Binary payload (image data).

Response: 201 OK

{
  "record_ids": ["generated-record-id"]
}

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X POST "http://localhost:8080/add-image?collection=default&encrypted=true" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@/path/to/encrypted-image"
import requests

headers = {
    'Content-Type': 'application/octet-stream'
}
params = {
    'collection': collection_name,
    'maxFaces': max_faces,
    'encrypted': encrypted
}
with open('/path/to/encrypted-image', 'rb') as image:
    response = requests.post(
        'http://localhost:8080/add-image',
        headers=headers,
        params=params,
        data=image
)

Utilities

Decrypt Payload

POST /decrypt

Decrypts a previously encrypted payload.

Request Body
Content-Type: application/octet-stream
Binary payload (encrypted data).

Response: 200 OK

Returns decrypted image data (Content-Type: image/jpeg).

Response: 400 Bad Request

{
  "status": 400,
  "message": "Exception message"
}

Example Request

curl -X POST "http://localhost:8080/decrypt" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@/path/to/encrypted-image" \
  -o "/path/to/decrypted-image.jpg"
import requests

headers = {
    'Content-Type': 'application/octet-stream'
}
with open('/path/to/encrypted-image', 'rb') as encrypted_image:
    response = requests.post(
        'http://localhost:8080/decrypt',
        headers=headers,
        data=encrypted_image
    )
with open('/path/to/decrypted-image.jpg', 'wb') as decrypted_image:
    decrypted_image.write(response.content)