Appearance
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
| Environment | URL |
|---|---|
| Sandbox | https://api-test.streamline.laboremus.ug/idv/api/facematches?v=2.0 |
| Production | https://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:
| Method | Header/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
| Name | Type | Required | Description |
|---|---|---|---|
| v | string | Yes | API version. Defaults to 2.0 |
Request Body(multipart/form-data)
| Name | Type | Required | Description |
|---|---|---|---|
| externalReference | string | No | Your reference ID to track this request |
| sourceImage | File (png, jpeg, jpg) | Yes | Selfie image of the person to verify |
| targetImage | File (png, jpeg, jpg) | Yes | Front of the identification document with the photo |
| nin | string | No | NIN 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
| Name | Type | Description |
|---|---|---|
| id | string | Unique identifier for this request |
| requestUri | string or null | URL to retrieve the request status and results |
| status | string (Enum: Pending, Completed, Failed) | Current processing status of the request |
| externalReference | string or null | Your 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
| Name | Type | Description |
|---|---|---|
| type | string or null | Type of error response |
| title | string or null | The title of the error response |
| status | integer(int32) | The status of the error response |
| traceId | string or null | The traceId of the error request producing the error |
| errors | object | Object defining the errors |
errors
| Name | Type | Description |
|---|---|---|
| property | Array of strings | The definition of the errors |
401 Not authorized to access the endpoint
application/json
| Name | Type | Description |
|---|---|---|
| error | object(Error) | Type of error response |
Error
| Name | Type | Description |
|---|---|---|
| code | string or null | The Error code |
| message | string or null | The Error message |
403 Refuse to authorize access to the endpoint
application/json
| Name | Type | Description |
|---|---|---|
| error | object(Error) | Type of error response |
Error
| Name | Type | Description |
|---|---|---|
| code | string or null | The Error code |
| message | string or null | The Error message |
404 Request does not exist
application/json
| Name | Type | Description |
|---|---|---|
| error | object(Error) | Type of error response |
Error
| Name | Type | Description |
|---|---|---|
| code | string or null | The Error code |
| message | string or null | The Error message |
500 The server encountered an unexpected error
application/json
| Name | Type | Description |
|---|---|---|
| error | object(Error) | Type of error response |
Error
| Name | Type | Description |
|---|---|---|
| code | string or null | The Error code |
| message | string or null | The Error message |