# Face Validation

## Introduction

Incode performs two validations related to a face (or selfie image):

* **Liveness validation**: Performed as soon as you add a selfie image to a session via the endpoint `/omni/add/face/third-party?imageType=selfie`. It protects you against someone uploading a pre-existing photo and claiming it's a selfie.
* **Face Match validation**: Compares the selfie image against the face that appears on an ID uploaded as part of the same session. This check is performed when you call the endpoint `/omni/process/face?imageType=selfie`. It will not work if you have not already uploaded an ID, so it's important to perform these steps in the order we've discussed them (see [previous step](doc:api-onboarding-id-validation)).

Face validation requires these two endpoint calls and you must perform them in the order shown:

* <Anchor label="Add face/Selfie image" target="_blank" href="ref:addfacebythirdparty">Add face/Selfie image</Anchor>
* <Anchor label="Process face" target="_blank" href="ref:processface">Process face</Anchor>

## Header requirements

Both endpoints require these header values:

| Header                 | Value                                                                                    |
| :--------------------- | :--------------------------------------------------------------------------------------- |
| `x-api-key`            | The API key provided to you by Incode.                                                   |
| `api-version`          | "1.0"                                                                                    |
| `X-Incode-Hardware-Id` | The <Glossary>Session Token</Glossary> obtained when you started the onboarding session. |

## Body/image requirements

Images must be provided in the request body as a base64 encoded string. They must meet these requirements:

* Minimum of 1000 pixels on one dimension, either width or height.
* Cannot exceed 10 MB as mentioned in the [limitations of the API](ref:introduction) documentation.

## Sample Code

### Add face

```curl
curl --location 'https://demo-api.incodesmile.com/omni/add/face/third-party?imageType=selfie' \
--header 'Content-Type: application/json' \
--header 'api-version: 1.0' \
--header 'x-api-key: <your_api_key>' \
--header 'X-Incode-Hardware-Id: <your_session_token>' \
--data '{
    "base64Image": ""
}'
```
```Text Nodejs
const axios = require('axios');
const fs = require('fs');

// Read your image file and encode as base64
const imageFilePath = 'path/to/your/image.jpg';
const base64 = fs.readFileSync(imageFilePath, { encoding: 'base64' });

const data = JSON.stringify({
  base64Image: base64
});

const config = {
  method: 'post',
  url: 'https://demo-api.incodesmile.com/omni/add/face/third-party?imageType=selfie',
  headers: { 
    'Content-Type': 'application/json', 
    'api-version': '1.0', 
    'x-api-key': '<your_api_key>',
    'X-Incode-Hardware-Id': '<your_session_token>'
  },
  data : data
};

axios(config).then(function (response) {
  console.log(response.data);
});

```
```java
var client = HttpClient.newHttpClient();

// Read your image file and encode as base64
Path imagePath = Path.of("path/to/your/image.jpg");
String base64 = Base64.getEncoder().encodeToString(Files.readAllBytes(imagePath));

var request = HttpRequest.newBuilder()
  .uri(URI.create("https://demo-api.incodesmile.com/omni/add/face/third-party?imageType=selfie"))
  .header("Content-Type", "application/json")
  .header("api-version", "1.0")
  .header("x-api-key", "<your_api_key>")
  .header("X-Incode-Hardware-Id", "<your_session_token>")
  .POST(BodyPublishers.ofString("{\"base64Image\":\"" + base64 + "\"}"))
  .build();

var response = client.send(request, BodyHandlers.ofString());
System.out.println(response.body());

```
```csharp
using var client = new HttpClient();

// Read your image file and encode as base64
var imageFilePath = "path/to/your/image.jpg";
var base64 = Convert.ToBase64String(File.ReadAllBytes(imageFilePath));

var json = "{\"base64Image\":\"" + base64 + "\"}";
var content = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("api-version", "1.0");
client.DefaultRequestHeaders.Add("x-api-key", "<your_api_key>");
client.DefaultRequestHeaders.Add("X-Incode-Hardware-Id", "<your_session_token>");

var response = await client.PostAsync("https://demo-api.incodesmile.com/omni/add/face/third-party?imageType=selfie", content);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);


```
```python
import requests
import base64

# Read your image file and encode as base64
image_file_path = 'path/to/your/image.jpg'
with open(image_file_path, "rb") as image_file:
    base64 = base64.b64encode(image_file.read()).decode('utf-8')

url = "https://demo-api.incodesmile.com/omni/add/face/third-party?imageType=selfie"

payload = {
    "base64Image": base64
}
headers = {
    'Content-Type': 'application/json',
    'api-version': '1.0',
    'x-api-key': '<your_api_key>',
    'X-Incode-Hardware-Id': '<your_session_token>'
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

```

After a face has been added successfully, you can see the liveness score by going to Dashboard > Sessions, then locating and selecting the session.  To learn more the request / response for this endpoint, see the [Add face/Selfie image](ref:addfacebythirdparty) API endpoint documentation.

### Process face

```curl
curl --location 'https://demo-api.incodesmile.com/omni/process/face?imageType=selfie' \
--header 'Content-Type: application/json' \
--header 'api-version: 1.0' \
--header 'x-api-key: <your_api_key>' \
--header 'X-Incode-Hardware-Id: <your_session_token>' \
--data '{}'
```
```javascript Nodejs
const axios = require('axios');
const data = JSON.stringify({});

const config = {
  method: 'post',
  url: 'https://demo-api.incodesmile.com/omni/process/face?imageType=selfie',
  headers: { 
    'Content-Type': 'application/json', 
    'api-version': '1.0', 
    'x-api-key': '<your_api_key>',
    'X-Incode-Hardware-Id': '<your_session_token>'
  },
  data : data
};

axios(config).then(function (response) {
  console.log(response.data);
});

```
```java
var client = HttpClient.newHttpClient();

var request = HttpRequest.newBuilder()
  .uri(URI.create("https://demo-api.incodesmile.com/omni/process/face?imageType=selfie"))
  .header("Content-Type", "application/json")
  .header("api-version", "1.0")
  .header("x-api-key", "<your_api_key>")
  .header("X-Incode-Hardware-Id", "<your_session_token>")
  .POST(BodyPublishers.ofString("{}"))
  .build();

var response = client.send(request, BodyHandlers.ofString());
System.out.println(response.body());

```
```csharp
using var client = new HttpClient();

var json = "{}";
var content = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("api-version", "1.0");
client.DefaultRequestHeaders.Add("x-api-key", "<your_api_key>");
client.DefaultRequestHeaders.Add("X-Incode-Hardware-Id", "<your_session_token>");

var response = await client.PostAsync("https://demo-api.incodesmile.com/omni/process/face?imageType=selfie", content);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);


```
```python
import requests

url = "https://demo-api.incodesmile.com/omni/process/face?imageType=selfie"

payload = {}
headers = {
    'Content-Type': 'application/json',
    'api-version': '1.0',
    'x-api-key': '<your_api_key>',
    'X-Incode-Hardware-Id': '<your_session_token>'
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

```

After a face has been processed successfully, you can see the face-match score by going to Dashboard > Sessions, then locating and selecting the session. To learn more the request / response for this endpoint, see the [Process face](ref:processface) API endpoint documentation.
