Skip to content
On this page

Create Face Match Request

Submit a request to verify that a selfie matches the photo on an identification document (national ID or driver's license), or submit a NIN alongside a selfie to match against the photo held by the authority. Requests are queued and processed asynchronously.

Endpoints

EnvironmentURL
Sandboxhttps://api-test.streamline.laboremus.ug/idv/api/facematches?v=2.0
Productionhttps://api.streamline.laboremus.ug/idv/api/facematches?v=2.0

Request

Request Type: POST

Authorization

Follow steps in the Authorization section to obtain an access token

INFO

Always add your Subscription key to the request.

Subscription Key

Include your subscription key in every request using one of these methods:

MethodHeader/Parameter
Header (recommended)Ocp-Apim-Subscription-Key: <your_key>
Query parameter?subscription-key=<your_key>
bash
curl --request POST \
  --url 'https://api.example.com/endpoint' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Ocp-Apim-Subscription-Key: <your_subscription_key>' \
  --header 'Content-Type: application/json' \
  --data '{"key": "value"}'
curl --request POST \
  --url 'https://api.example.com/endpoint' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Ocp-Apim-Subscription-Key: <your_subscription_key>' \
  --header 'Content-Type: application/json' \
  --data '{"key": "value"}'
js
const response = await fetch(API_ENDPOINT, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
const response = await fetch(API_ENDPOINT, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
python
import requests

response = requests.post(
    API_ENDPOINT,
    headers={
        'Authorization': f'Bearer {access_token}',
        'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
        'Content-Type': 'application/json'
    },
    json=data
)
import requests

response = requests.post(
    API_ENDPOINT,
    headers={
        'Authorization': f'Bearer {access_token}',
        'Ocp-Apim-Subscription-Key': '<your_subscription_key>',
        'Content-Type': 'application/json'
    },
    json=data
)
csharp
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<your_subscription_key>");

var content = new StringContent(
    JsonSerializer.Serialize(data),
    Encoding.UTF8,
    "application/json"
);

var response = await client.PostAsync(API_ENDPOINT, content);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<your_subscription_key>");

var content = new StringContent(
    JsonSerializer.Serialize(data),
    Encoding.UTF8,
    "application/json"
);

var response = await client.PostAsync(API_ENDPOINT, content);
java
HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(API_ENDPOINT))
    .header("Authorization", "Bearer " + accessToken)
    .header("Ocp-Apim-Subscription-Key", "<your_subscription_key>")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(API_ENDPOINT))
    .header("Authorization", "Bearer " + accessToken)
    .header("Ocp-Apim-Subscription-Key", "<your_subscription_key>")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Query Parameters

NameTypeRequiredDescription
vstringYesAPI version. Defaults to 2.0

Request Body(multipart/form-data)

NameTypeRequiredDescription
externalReferencestringNoYour reference ID to track this request
sourceImageFile (png, jpeg, jpg)YesSelfie image of the person to verify
targetImageFile (png, jpeg, jpg)YesFront of the identification document with the photo
ninstringNoNIN of the individual used to match against the authority photo instead of targetImage

File Requirements

Images must be sent as multipart/form-data. Maximum file size is 5 MB per image.

Example Request (Image vs Image)

Content-Type

multipart/form-data

bash
curl --request POST \
  --url 'https://api-test.streamline.laboremus.ug/idv/api/facematches?v=2.0' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Ocp-Apim-Subscription-Key: <subscription_key>' \
  --form 'sourceImage=@selfie.jpg' \
  --form 'targetImage=@id_front.jpg' \
  --form 'externalReference=my-ref-12345'
curl --request POST \
  --url 'https://api-test.streamline.laboremus.ug/idv/api/facematches?v=2.0' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Ocp-Apim-Subscription-Key: <subscription_key>' \
  --form 'sourceImage=@selfie.jpg' \
  --form 'targetImage=@id_front.jpg' \
  --form 'externalReference=my-ref-12345'

Example Request (NIN + Selfie)

Content-Type

multipart/form-data

bash
curl --request POST \
  --url 'https://api.xxxxx.ug/idv/api/identities/biometrics/match?v=2.0' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'ocp-apim-subscription-key: <subscription_key>' \
  --form 'ExternalReference=461c535e-0dbd-4e27-b223-e6386f6dc635' \
  --form 'Nin=CM9400810629JH' \
  --form 'Selfie=@/path/to/selfie.jpg'
curl --request POST \
  --url 'https://api.xxxxx.ug/idv/api/identities/biometrics/match?v=2.0' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'ocp-apim-subscription-key: <subscription_key>' \
  --form 'ExternalReference=461c535e-0dbd-4e27-b223-e6386f6dc635' \
  --form 'Nin=CM9400810629JH' \
  --form 'Selfie=@/path/to/selfie.jpg'

Response

A successful request returns a 202 Accepted status with details to track the face match processing.

Response Fields

NameTypeDescription
idstringUnique identifier for this request
requestUristring or nullURL to retrieve the request status and results
statusstring (Enum: Pending, Completed, Failed)Current processing status of the request
externalReferencestring or nullYour reference ID if provided in the request

Example Response

Content-Type

application/json

json
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "requestUri": "/api/biometrics/facematch/497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "status": "Pending",
  "externalReference": "my-ref-12345"
}
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "requestUri": "/api/biometrics/facematch/497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "status": "Pending",
  "externalReference": "my-ref-12345"
}

Next Steps

Use the id or requestUri to poll for results using the Get Facematch Details endpoint.

Error Response

400 The request data is invalid

application/json

NameTypeDescription
typestring or nullType of error response
titlestring or nullThe title of the error response
statusinteger(int32)The status of the error response
traceIdstring or nullThe traceId of the error request producing the error
errorsobjectObject defining the errors

errors

NameTypeDescription
propertyArray of stringsThe definition of the errors

401 Not authorized to access the endpoint

application/json

NameTypeDescription
errorobject(Error)Type of error response

Error

NameTypeDescription
codestring or nullThe Error code
messagestring or nullThe Error message

403 Refuse to authorize access to the endpoint

application/json

NameTypeDescription
errorobject(Error)Type of error response

Error

NameTypeDescription
codestring or nullThe Error code
messagestring or nullThe Error message

404 Request does not exist

application/json

NameTypeDescription
errorobject(Error)Type of error response

Error

NameTypeDescription
codestring or nullThe Error code
messagestring or nullThe Error message

500 The server encountered an unexpected error

application/json

NameTypeDescription
errorobject(Error)Type of error response

Error

NameTypeDescription
codestring or nullThe Error code
messagestring or nullThe Error message

Tech Served Right