NAV Navbar
  • Introduction
  • Authentication
  • API Design
  • Phrase Verifier
  • Confidence Scoring
  • Android SDK
  • Errors
  • Release Notes
  • Introduction

    Welcome to the Liopa LipSecure API!

    We have example calls in cURL and language bindings in Python, JavaScript (NodeJS) and Java to follow soon. You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.


    LipSecure uses API keys to grant access to the API. For access to the API contact us through our website.

    LipSecure expects for the API key to be included in all API requests to the server in a header as follows:

    X-API-Key: 38332b622aea11e8b103a860b60304d5

    API Design

    The purpose of the LipSecure service is to prove liveness. Given a video of a person asked to recite a given phrase, LipSecure will indicate the confidence that the person was responding correctly.

    For more information and examples contact us.

    The liveness check process is completed in two phases:
    1. Request a challenge phrase and start a transaction, receiving a transaction ID and a phrase
    2. Send a video of the user reciting the challenge phrase with the transaction ID and receive a confidence score


    The base URL for the LipSecure API is:

    The API is designed to always return a consistent response from each endpoint. As such, errors are embedded in the JSON body. Standard HTTP codes are used to denote common problems. More details can be found in the errors section.

    Phrase Verifier

    1. Get a random challenge phrase from LipSecure

    curl -X POST "" -H  "X-API-Key: 38332b622aea11e8b103a860b60304d5"

    The above command returns JSON structured like this:

          "transactionId": "ef5a0ae2-884e-4106-b247-b332a0f9dd88",

    This endpoint requests a random phrase from the LipSecure Phrase Verifier, returning the phrase and a transaction ID. The transaction ID will be used in subsequent calls.

    Endpoint: challenge
    Method: POST
    Header: X-API-KEY : <key>
    Returns: 200 OK with JSON body

    2. Verify a recorded phrase

    The last part of the URI contains the transaction ID from the previous call. The video file should consist of a user reciting the phrase returned in the previous call.

    curl -X POST "" \
        -H  "X-API-Key: 38332b622aea11e8b103a860b60304d5" \
        -F ‘file=@<video_file>’

    The above command returns JSON structured like this:

        "transactionId" : "ef5a0ae2-884e-4106-b247-b332a0f9dd88",
        "phrase" : "597692",
        "error" :
                "type" : "",

    This endpoint verifies the phrase in the provided video matches what was expected.

    Endpoint: verifier/<transactionId>
    Method: POST
    Header: X-API-KEY : <key>
    Type: Multipart upload with video included via the file attribute
    Returns: 200 OK with JSON body

    The transaction ID must match what was returned from the preceding call to challenge. The uploaded video file must be labelled with a file attribute.

    Video File Payload

    The payload should be a compressed video file, containing a subject reciting the phrase. Resolution, frame rate, bitrate etc are all flexible. As a guideline from a mobile phone forward-facing camera, use MPEG-4 encoding of 640x480 video at 15 frames-per-second with a 1kbps bitrate.

    Confidence Scoring

    The score which is returned to the user ranges from 0 to 100 and represents the estimated percentage probability that the video was a valid ‘live’ response to the challenge phrase. For example, if the score returned was 90 then this means that there is a 10% chance that the video was an imposter attack.

    As a brief guide to setting a threshold, our tests have shown that for a threshold of 98, there is approximately a 2% chance of False Acceptance and a 4% chance of False Rejection and for a score of 99, we have no recorded False Acceptances in any test cases and approximately 5% chance of False Rejection.

    The scores which LipSecure calculates for each video are influenced by a range of factors during the recording process, including illumination conditions etc. but they are chiefly affected by how clearly the person moves their lips while speaking the digits.

    For each application in which LipSecure will be deployed there may be certain minimum threshold confidence scores which will be appropriate so we will allow the application developers to set their own threshold levels rather than prescribing them.

    Android SDK

    An Android SDK is available for integrating LipSecure in an existing or new Android application.

    Version SDK Download MD5 Hash Documentation
    1.0.0 SDK b2ff566b8c2039ff2c33f18abe641c82 Dev Guide Release Notes


    The JSON format for errors is as follows:

    "error" :
            "type" : # one of 'client', 'server' or 'user',
            "code": <id>,
            "message": # string with description

    The LipSecure service returns JSON objects with a standard format to simplify the engineering effort of integration. The JSON object will contain an error object, that normally will have a status of 'no error'.

    There are three types of error:
    1. User
    2. Client
    3. Server

    User errors are intended to be passed on so the user can correct the problem and retry. Examples of user errors are:
    1. Video too short
    2. Poor illumination
    3. Face not presented to the camera correctly

    Client errors are usually the result of integration problems and can be mitigated using error handling during integration with LipSecure. Examples of client errors are:
    1. Bad request (400) - the request has not been correctly created, e.g. not using the correct attribute file for the video upload
    2. Unauthorized (401) - the incorrect API key is inserted into the header

    Server errors are due to problems within the LipSecure service. This should happen rarely, but if it does then neither the user nor client can remedy the situation. Server errors can be resolved by contacting

    List of error codes

    Error Code Type Meaning and Remediation
    xxx User Pass on the error to the user for another attempt
    400 Client Bad Request - the request is invalid, check the request format
    401 Client Unauthorized - check the URI and API key
    500 Server Internal Server Error - contact

    Release Notes

    Version Date Notes
    1.1 2019-01-08 Updated information on Android SDK
    1.0 2018-11-23 Initial API release