Performs a one-to-one comparison of the submitted live images with the submitted ID photo in order to verify whether the live images and ID photo belong to the same person.
Additionally, if not explicitely denied, liveness detection is performed on the provided live images. This is done by internally calling into the LivenessDetection API.
PhotoVerify is a service, which uses one photo, e.g. a passport image from an ID document, and compares that to one or two "live" images of a person, to find out whether the persons shown are the same. No classes are created, no templates or patterns are stored. It fulfills all requirements for an anonymous ID proofing service.
To make a decision about the similarity of the photo and the live images, an accuracy level is calculated (returned in the verification_level field). The higher the accuracy level, the better the faces on the images match. We highly recommend to use high accuracy levels, at least level 4, for your decision. Lower accuracy levels can be used with low quality ID photos (e.g. scanned passport images), where a higher accuracy cannot be reached any more.
POST /api/v1/photoverify
Content type: application/json
{
"liveImages": [
{
"image": "string",
"tags": [
"string"
]
}
],
"photo": "string",
"disableLivenessDetection": false
}
The PhotoVerify request object has a the fields as follows:
liveImages
photo
disableLivenessDetection
liveImages
.
If you do not want to perform a liveness detection at all, simply set this flag to true
.
This API requires a valid JWT in the Authorization request header and accepts an optional reference number.
Authorization | Required Bearer authentication. Please refer to BWS API Authentication for a description of how to provide a valid JWT here. |
Reference-Number | Optional, client specific reference number, which will be added to the BWS bookkeeping as well as to the response header. You typically use this reference to link the resulting BWS bookkeeping entries with your logs. |
Content type: application/json
{
"status": "SUCCEEDED",
"errors": [
{
"errorCode": "string",
"message": "string"
}
],
"imageProperties": [
{
"rotated": 0,
"faces": [
{
"leftEye": {
"x": 0,
"y": 0
},
"rightEye": {
"x": 0,
"y": 0
},
"textureLivenessScore": 0,
"motionLivenessScore": 0,
"movementDirection": 0
}
],
"qualityScore": 0,
"qualityAssessments": [
{
"check": "string",
"score": 0,
"message": "string"
}
],
"frameNumber": 0
}
],
"photoProperties": {
"rotated": 0,
"faces": [
{
"leftEye": {
"x": 0,
"y": 0
},
"rightEye": {
"x": 0,
"y": 0
},
"textureLivenessScore": 0,
"motionLivenessScore": 0,
"movementDirection": 0
}
],
"qualityScore": 0,
"qualityAssessments": [
{
"check": "string",
"score": 0,
"message": "string"
}
],
"frameNumber": 0
},
"verificationLevel": "NOT_RECOGNIZED",
"verificationScore": 0,
"live": true,
"livenessScore": 0
}
On success the API returns a PhotoVerify response object with the fields as follows:
status
errors
imageProperties
photoProperties
verificationLevel
The actual level of accuracy the specified photo complies with. A decision about the similarity of the photo and the live images should be made on this response field. We recommend to at least only accept accuracy level 4 or higher.
The calculated accuracy level correlates with a false accepted rate (FAR) as follows:
Level 5 | FAR of 0.001% | very high propability that the persons on the images are the same - the identity can be seen as approved |
Level 4 | FAR of 0.01% | good propability that the persons on the images are the same - recommended as minimum accepted level |
Level 3 | FAR of 0.1% | moderate accuracy level |
Level 2 | FAR of 0.25% | a relatively high false acceptance rate, should be the lowest acceptable level when using bad photo scans |
Level 1 | FAR of 0.5% | we do not recommend to use this level, which is intended for really bad ID photos only |
Not recognized | Not recognized at all. | when reported with no additional error, the photo simply does not match with the live image(s) |
verificationScore
An informative verification score (a value between 0.0 and 1.0) that reflects the verification level. The higher the score, the more likely the live images and ID photo belong to the same person. If this score is exactly 0.0, it has not been calculated.
live
true
, the provided images are supposed to be recorded from a live person. No errors are reported in this case.
When this field is set to false
, there is at least one error reported that explains, why the provided images are not supposed to be recorded from a live person.
livenessScore
An informative liveness score (a value between 0.0 and 1.0) that reflects the confidence level of the live decision. The higher the score, the more likely the person is a live person. If this score is exactly 0.0, it has not been calculated and an error has been be reported.
In case that the live
field is set to false
, at least one of the following errors is reported in the errors
field:
FullyVisibleFace
quality check results.The call returns one of the standard HTTP status codes, e.g.:
code
and message
.All successful BWS calls return a response header containing additional information about the request:
jobid | The Job-ID (a GUID) that has been assigned to this BWS call. |
bws-version | The version of the BWS gRPC service. |
reference-number | An optional reference number as provided in the request header. |
date | The timestamp when the request has been received at the server. |
... | Other headers that might have been added by the server (NGINX, Kestrel, ...) that was handling the request. |
Here is a short example of how to call into the PhotoVerify RESTful JSON API using live images and a photo loaded from files.
Please refer to BWS API Authentication for a description of the methods CreateAuthenticatedClient and GenerateToken.
This sample code makes use of some C# JSON data transfer objects, which you can find in the BwsJsonDto.cs source file.
using HttpClient httpClient = CreateAuthenticatedClient(new Uri(options.Host), GenerateToken(options.ClientId, options.Key));
var request = new PhotoVerifyRequest {
Photo = Convert.ToBase64String(File.ReadAllBytes(options.Photo)),
DisableLivenessDetection = false };
foreach (string file in options.Files)
{
request.LiveImages.Add(new ImageData { Image = Convert.ToBase64String(File.ReadAllBytes(file)) });
}
var response = await httpClient.PostAsync("/api/v1/photoverify", JsonContent.Create(request));
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadFromJsonAsync<PhotoVerifyResponse>();
// ...
Console.WriteLine($"VerificationLevel: {responseContent.VerificationLevel} ({responseContent.VerificationScore})");
Console.WriteLine($"Live: {responseContent.Live} ({responseContent.LivenessScore})");
}
else
{
Console.WriteLine($"Server response: {response.StatusCode}");
}
todo
todo