This is intended for technical developer who will implement One Smart Lab’s Rest API Services

VideoVerify ($0.03 USD per call)

  • confirm that face in a selfie video matches the ID
  • confirm that the user has spoken a 6 digit number that your app generates and asks the user to repeat
  • confirm that the face in the selfie is not spoofed

SpoofDetect_Video ($0.03 USD per call)

  • confirm that face in video is not being spoofed

Current API version is 1.1.

For apps needing more “industrial strength” verification of the user, we recommend VideoVerify since it uses both deep neural network and behavioral spoof detection. It is much harder to “fool” the AI with a video than a single photo because One Smart Lab AI model is able to pick up subtle nuances in video time series.

 


Create an API Key


 

/videoverify

URL EndPoint:

  • https://api.onesmartlab.com/v1.1/videoverify

POST Parameters:

  • id_card – HTTP multipart POST data for ID card that contains the face of the person you are trying to authenticate
  • video – HTTP multipart POST  data for video that contains the person’s selfie taken real time
    • This video must be valid MP4 video file
    • The speaker in the video must clearly show his/her face speaking the 6 digit audiochallenge that your app. See example
    • Please view the video guidelines as it contains detailed information on how the video should be taken
  • audiochallenge – sequence of 6 digits your app has requested the user to speak in the video
  • languageCode (notice the capital “C”) – language that the user has spoken in, such as “en-US” (view the accepted language codes)
  • api_key – your API key

 

API Call Example

curl:

id_card=/path/to/your/id_card.jpg
video=/path/to/your/selfie_video.mp4
server="https://api.onesmartlab.com/v1.1/videoverify"
audiochallenge="YOUR_6_DIGIT_AUDIOCHALLENGE"
languageCode="YOUR_LANGUAGE_CODE"
api_key="YOUR_API_KEY"

curl -X POST \
  -F "api_key=$api_key" \
  -F "id_card=@$id_card" \
  -F "video=@$video" \
  -F "audiochallenge=$audiochallenge" \
  -F "languageCode=$languageCode"
  $server

 

python:

import requests


data = {  
  "audiochallenge" : "YOUR_AUDIO_CHALLENGE",
  "languageCode" : "YOUR_LANGUAGE_CODE",
  "api_key" : "YOUR_API_KEY"
}

files = {
  "id_card" : open('/path/to/your/id_card.jpg', 'rb'), 
  "video" : open('/path/to/your/selfie_video.mp4', 'rb')
}
r = requests.post("https://api.onesmartlab.com/v1.1/videoverify", data=data, files=files)
print(r.text)

 

php:

$url = "https://api.onesmartlab.com/v1.1/photoverify"

$data = array(
    "api_key"   => "YOUR_API_KEY",
    "audiochallenge" => "YOUR_AUDIO_CHALLENGE", 
    "languageCode"  => "YOUR_LANGUAGE_CODE",
    "id_card" => new \CurlFile("/path/to/your/selfie.jpg", 'image/jpeg', 'id_pic.jpg'),
    "video" => new \CurlFile("/path/to/your/selfie_video.mp4", 'video/mp4', 'selfie_video.mp4')
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($curl);

curl_close($curl);

print_r($result)

 

Response:

  • if error exists
    • {“error” : “SOME_ERROR”}
  • sample successful response:
{
    "predictions":{
        "duration":"55.86",
        "end":1534534753.1725538,
        "model_input":{
            "audiochallenge":"123457",
            "languageCode":"th-TH",
            "video":{
                "fps":30,
                "frames":105,
                "height":480,
                "width":640
            }
        },
        "model_output":{
            "audio_challenge_passed":true,
            "face_distance_avg":0.5534744282563527,
            "face_sameness":0.9904761904761905,
            "largest_face_to_frame_ratio":0.334375,
            "non_spoof_detected":1.0,
            "single_face_in_frames":1.0,
            "transcription":{
                "results":[
                    {
                        "alternatives":[
                            {
                                "confidence":0.95064026,
                                "transcript":"1 2 3 4 5 7 "
                            }
                        ]
                    }
                ]
            }
        },
        "model_params":{
            "FACE_TO_FRAME_RATIO_MAX":0.7,
            "THRESHOLD_FACE_SIMILARITY":0.9,
            "THRESHOLD_L2_DISTANCE":0.9,
            "THRESHOLD_SPOOF":0.9
        },
        "start":1534534697.3109004,
        "verification":{
            "breakdown":{
                "audio_challenge_passed":true,
                "face_to_frame_width_ratio_passed":true,
                "not_spoof_passed":true,
                "video_face_no_change_passed":true,
                "video_face_to_id_face_passed":true
            },
            "status":true
        }
    },
    "success":true
}

How to Determine if Self Video Matches the ID  & isn’t Spoofing

Check field – json[“predictions”][“verification”][“status”]

 

Explanation of the Fields

{
    "predictions":{
        "duration":"How long the model took to run",
        "end":"Time model prediction ended, Milliseconds since Unix Epoch",
        "model_input":{
            "audiochallenge":"sequence of numbers that the user is supposed to say in the video",
            "languageCode":"language code passed to the model",
            "video":{
                "fps":"Frames per second in video",
                "frames":"# of frames in video",
                "height":"Video height",
                "width":"Video width"
            }
        },
        "model_output":{
            "audio_challenge_passed":"whether or not the user has spoken the sequence of numbers",
            "face_distance_avg":"[MODERATION_FIELD] How far the face is from the ID. The closer the face to the ID, the lower this number should be. We currently use THRESHOLD_FACE_SIMILARITY.",
            "face_sameness":"How 'same' the face looks in the entire video. Closer to 1 is better.",
            "largest_face_to_frame_ratio":"[MODERATION_FIELD] How big the face width is relative to the video frame width, in percentage. We currently use FACE_TO_FRAME_RATIO_MAX as acceptable max limit.",
            "non_spoof_detected":"[MODERATION_FIELD] How likely that the faces found are spoofed. Closer to 1 means more normal. Closer to 0 means more likely to be spoofing",
            "single_face_in_frames":"[MODERATION_FIELD] Whether or not we found weird number of faces (i.e. not 1). Closer to 1 is better.",
            "transcription":{
                "results":[
                    {
                        "alternatives":[
                            {
                                "confidence":"Transcription confidence level - 1 is better",
                                "transcript":"Transcription from the Audio"
                            }
                        ]
                    }
                ]
            }
        },
        "model_params":{
            "FACE_TO_FRAME_RATIO_MAX":"0.7 but YOU CAN SAFELY IGNORE. Internal Value for OneSmartLab team" ,
            "THRESHOLD_FACE_SIMILARITY":"0.9 but YOU CAN SAFELY IGNORE. Internal Value for OneSmartLab team" ,
            "THRESHOLD_L2_DISTANCE":"0.9 but YOU CAN SAFELY IGNORE. Internal Value for OneSmartLab team" ,
            "THRESHOLD_SPOOF":"0.9 but YOU CAN SAFELY IGNORE. Internal Value for OneSmartLab team"
        },
        "start":"Time model prediction started, Milliseconds since Unix Epoch""
        "verification":{
            "breakdown":{
                "audio_challenge_passed":"Whether or not the audio in the video transcribes to match the audiochallenge ",
                "face_to_frame_width_ratio_passed":"Whether or not the face to frame ratio is acceptable",
                "not_spoof_passed": "whether or not spoofing in the photo /video was detected",
                "video_face_no_change_passed":"whether or not the photo /video matches the ID",
                "video_face_to_id_face_passed":"whether or not the face in the photo /video is consistent"
            },
            "status":"True if ALL the breakdown are true. False otherwise."
        }
    },
    "success":"true if everything ran correctly"
}






 

 

 

 

/spoofdetect_video

URL EndPoint:

  • https://api.onesmartlab.com/v1.1/spoofdetect_video

POST Parameters:

  • video – HTTP multipart POST  data for video that contains the person’s selfie taken real time
    • This video must be valid MP4 video file
    • Please view the video guidelines as it contains detailed information on how the video should be taken
  • api_key – your API key

 

API Call Example

curl:

video=/path/to/your/selfie_video.mp4
server="https://api.onesmartlab.com/v1.1/spoofdetect_video"
api_key="YOUR_API_KEY"

curl -X POST \
  -F "api_key=$api_key" \
  -F "video=@$video" \
  $server

 

python:

import requests


data = {  
  "api_key" : "YOUR_API_KEY"
}

files = {
  "video" : open('/path/to/your/selfie_video.mp4', 'rb')
}
r = requests.post("https://api.onesmartlab.com/v1.1/spoofdetect_video", data=data, files=files)
print(r.text)

 

php:

$url = "https://api.onesmartlab.com/v1.1/spoofdetect_video"

$data = array(
    "api_key"   => "YOUR_API_KEY",
    "video" => new \CurlFile("/path/to/your/selfie_video.mp4", 'video/mp4', 'selfie_video.mp4')
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($curl);

curl_close($curl);

print_r($result)

 

Response:

  • if error exists
    • {“error” : “SOME_ERROR”}
  • sample successful response:
{  
    "predictions":{  
        "duration":"28.58",
        "end":1539746503.5104527,
        "metadata":{  
            "avg_face_to_frame_width_ratio":"0.59",
            "confidence":"1.00"
        },
        "model_input":{  
            "video":{  
                "fps":30,
                "frames":105,
                "height":160,
                "width":160
            }
        },
        "model_params":{  
            "FACE_TO_FRAME_RATIO_MAX":0.6,
            "THRESHOLD_FACE_SIMILARITY":0.9,
            "THRESHOLD_L2_DISTANCE":0.9,
            "THRESHOLD_SPOOF":0.9
        },
        "start":1539746474.9279783,
        "verification":{  
            "breakdown":{  
                "pct_face_to_frame_width_ratio_acceptable":"0.68",
                "pct_single_face_detected":"1.00",
                "pct_spoof_detected":"0.00"
            },
            "status":false
        }
    },
    "success":true
}

How to Determine if Self Video Matches the ID  & isn’t Spoofing

Check field – json[“predictions”][“verification”][“status”]

 

Explanation of the Fields

{  
    "predictions":{  
        "duration":"HOW MANY SECONDS IT TOOK TO PROCESS THE VIDEO",
        "end": "Time in MS when process completed",
        "metadata":{  
            "avg_face_to_frame_width_ratio":"Average ratio of face width to frame width",
            "confidence":"How confident the spoof detection was"
        },
        "model_input":{  
            "video":{  
                "fps":"Video FPS",
                "frames":"# of frames in video",
                "height":"video height",
                "width":"video width"
            }
        },
        "model_params":{  
            "FACE_TO_FRAME_RATIO_MAX": "Model parameter input: How wide the face should be relative to width of video width",
            "THRESHOLD_FACE_SIMILARITY":"Model parameter input: How close the faces detected in frames should be",
            "THRESHOLD_L2_DISTANCE":"Model parameter input: How close the faces detected in frames should be",
            "THRESHOLD_SPOOF":"Model parameter input: How certain the spoof detection confidences must be"
        },
        "start":"Time in MS when process started",
        "verification":{  
            "breakdown":{  
                "pct_face_to_frame_width_ratio_acceptable":"what percentage of faces detected in frames are below FACE_TO_FRAME_RATIO_MAX",
                "pct_single_face_detected":"what percentage of frames have exactly 1 face detected",
                "pct_spoof_detected":"How 'spoof'-y the video detected was"
            },
            "status": "True if pct_face_to_frame_width_ratio_acceptable > 0.95 AND pct_single_face_detected > 0.95 and pct_spoof_detected < 0.5"
        }
    },
    "success":"True if process ran to completion"
}





 


Create an API Key