> For the complete documentation index, see [llms.txt](https://legacy-docs.usesmileid.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://legacy-docs.usesmileid.com/products/for-individuals-kyc/smartselfie-tm-compare.md).

# SmartSelfie™ Compare

## **Overview**

The SmartSelfie™ Compare product lets you match and authenticate a genuine user's selfie with an existing photo on file.

In one step, you submit both:\
1\. the user's selfie and liveness images and\
2\. the image on file (eg. government authority image).

{% hint style="info" %}
With **SmartSelfie™ Compare**, a user will enrolled (registered) and Authenticated in one go instead of the two step process of **SmartSelfie™ Authentication** .
{% endhint %}

### Integration Options

Available on `Rest API`.

You can capture face images using the mobile and web SDKs and then submit via the REST APIs. To do this, see:

### Using the SmartSelfie™ Compare Product

Follow the steps below to perform a SmartSelfie™ Compare:

1. Make a job request that has your selfie and comparison photo
2. Upload the job requirements
3. Evaluate your result

### Making a Request

This API is designed to be more RESTFUL to ensure standardised consistency and stateless API implementation. Hence, it differs from our existing biometric products in two main ways:

1. It uses **header-based authentication** instead of body-based authentication. This means you will now add your authorisation params (timestamp, partner-id, and signature) in the HTTP-header. This
2. The responses are always **synchronous**. You can add a callback and recieve responses in the previous smile format. The synchronous nature of these responses means there are NO HUMAN REVIEWS at the submission stage. Hence there will be no PENDING or PROVISIONAL RESULTS.

#### Request Type and URLs

**Request Type**: `POST`

<table><thead><tr><th width="214">Environment</th><th>URL</th></tr></thead><tbody><tr><td>Sandbox</td><td><a href="https://testapi.smileidentity.com/v2/smart-selfie-compare">https://testapi.smileidentity.com/v2/smart-selfie-compare</a></td></tr><tr><td>Production</td><td><a href="https://api.smileidentity.com/v2/smart-selfie-compare">https://api.smileidentity.com/v2/smart-selfie-compare</a></td></tr></tbody></table>

{% hint style="danger" %}
This request must use the `multipart/form-data` MIME type. If you include a `Content-Type` header such as `multipart/form-data; boundary=ExampleBoundaryString`, ensure the boundary is correctly added. Most HTTP clients handle this automatically, so you can omit the header. [Learn more.](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Type)
{% endhint %}

#### Request Header

<table><thead><tr><th width="200">Key</th><th width="172">Value</th><th width="111">Required</th><th>Description</th></tr></thead><tbody><tr><td>SmileID-Timestamp</td><td>{{timestamp eg. 2021-08-12T17:57:00.614879}}</td><td>Yes</td><td>The timestamp that was used to calculate your signature (in ISO date/time format).</td></tr><tr><td>SmileID-Partner-ID</td><td>{{your_partner_id eg. 0001}}</td><td>Yes</td><td>This is your partner id which can be found on the side navigation panel of the <a href="https://portal.usesmileid.com/partner/dashboard">Smile ID partner portal</a></td></tr><tr><td>SmileID-Request-Signature</td><td>{{your_security_signature eg. aw234..}}</td><td>Yes</td><td>Your calculated access signature</td></tr></tbody></table>

{% hint style="success" %}
To prevent issues with authorisation errors, the timestamp must be in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) with a micro-second format of 3-digits. eg. `.809Z` for this timestamp: `2025-05-23T11:40:07.809Z`.
{% endhint %}

#### Request Body

<table><thead><tr><th width="244">Keys</th><th width="121">Type</th><th width="107">Required</th><th>Description</th></tr></thead><tbody><tr><td>user_id</td><td>string</td><td>Yes</td><td>The ID of the user to enroll after face comparison</td></tr><tr><td>selfie_image</td><td>File</td><td>Yes</td><td>Selfie image</td></tr><tr><td>comparison_image</td><td>File</td><td>Yes</td><td>Comparison image</td></tr><tr><td>comparison_image_type**</td><td>string</td><td>Yes</td><td>The type of comparison image it can be one of <code>ID_PHOTO</code>: photos from ID Authority <code>PORTRAIT</code> - A user's selfie or captured by an agent using <code>DOCUMENT</code> - photo of an ID document</td></tr><tr><td>liveness_images</td><td>File</td><td>Yes</td><td>There is a minimum of 4 and max of 8 liveness images you must send. It is recommended you send 8 liveness for a more validation process</td></tr><tr><td>partner_params</td><td>object</td><td>Yes</td><td>A JSON object containing the partner parameters below as well as any additional key value pairs you wish to include for tracking which will be returned in the response</td></tr><tr><td>allow_new_enroll</td><td>string {<code>true</code> or default: <code>false</code>}</td><td>No</td><td><p>A flag to re-enroll an existing user identified by the param <code>user_id</code></p><p>allow_new_enroll has a default value of false.</p></td></tr><tr><td>job_id</td><td>string</td><td>Yes</td><td>A value generated by you, so you can track jobs on your end. This value must be unique, can be any string and can follow your identifier convention</td></tr><tr><td>user_id</td><td>string</td><td>Yes</td><td>A value generated by you, so you can track users on your end. This value must be unique, can be any string and can follow your identifier convention</td></tr><tr><td>callback_url</td><td>string</td><td>Yes</td><td>An endpoint on the partner side where Smile ID will send the results of a job to in the form of a POST request (with no authorisation headers)</td></tr></tbody></table>

{% hint style="info" %}
Note: You will pass each liveness image as a separate parameter per image. in the form data. Do not pass it as an array collection
{% endhint %}

{% hint style="info" %}
\*\* Specifying the the right image type is important for successful outcomes. There is a difference between how we process `ID_PHOTO` and `PORTRAIT`. ID Authority images (ID\_PHOTO) might contain artefacts (such as watermarks, stamps etc) that we automatically make exceptions for.
{% endhint %}

**Example Request**

A sample request is as follows:

```shell
curl --request POST '/v2/smart-selfie-compare' \
--header 'Content-Type: multipart/form-data' \
--header 'SmileID-Timestamp: 2024-05-24T09:45:43.044Z' \
--header 'SmileID-Partner-ID: 0000' \
--header 'SmileID-Request-Signature: xxxx' \
--form 'user_id="user-id-uuid"' \
--form 'selfie_image=@"/somefilepath/selfie.jpg"' \
--form 'comparison_image="ID_PHOTO"' \
--form 'liveness_images=@"/somefilepath/liveness_0001.jpg"' \
--form 'liveness_images=@"/somefilepath/liveness_0002.jpg"' \
--form 'liveness_images=@"/somefilepath/liveness_0003.jpg"' \
--form 'liveness_images=@"/somefilepath/liveness_0004.jpg"' \
--form 'liveness_images=@"/somefilepath/liveness_0005.jpg"' \
--form 'liveness_images=@"/somefilepath/liveness_0006.jpg"' \
--form 'callback_url="https://some_webhook"' \
--form 'partner_params={"job_id": "firstprodfastauth6", "user_id": "user-id-uuid", "job_type":"3"}' \
--form 'allow_new_enroll="True"'

```

### Results Values

You have submitted the job to Smile ID to register your user, the following keys are sent to your callback:

<table data-header-hidden><thead><tr><th width="246">Name</th><th width="150">Type</th><th>Description</th><th>Return Values</th></tr></thead><tbody><tr><td><strong>Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td><td>Return Values</td></tr><tr><td>PartnerParams.job_id</td><td>String</td><td>A unique reference defined by you to keep track of the job</td><td></td></tr><tr><td>PartnerParams.job_type</td><td>String</td><td>The type of job you performed.</td><td></td></tr><tr><td>PartnerParams.user_id</td><td>String</td><td>A unique reference defined by you to keep track of the user</td><td></td></tr><tr><td>Code</td><td>String</td><td>Numeric value of the job outcome.</td><td>Full list of result codes below</td></tr><tr><td>Text</td><td>String</td><td>Textual value of the job outcome. Human readable value for the result.</td><td>Full list of result text below.</td></tr><tr><td>SmileJobID</td><td>String</td><td>The Smile internal reference number for the job</td><td></td></tr><tr><td>Liveness_Check</td><td>String</td><td>Liveness check on user provided liveness images</td><td><p>“Passed”</p><p>“Failed”</p></td></tr><tr><td>Selfie_Check</td><td>String</td><td>Passive liveness check on the user provided selfie</td><td><p>“Passed”</p><p>“Failed”</p></td></tr><tr><td>code</td><td>String</td><td>The error codes that match with</td><td><p>“Approved”</p><p>“Rejected”</p><p>“Provisionally Approved”</p><p>“Not Applicable”</p></td></tr><tr><td>Selfie_Provided</td><td>String</td><td>User provided a usable selfie</td><td><p>"Passed"</p><p>"Failed"</p></td></tr></tbody></table>

The response includes detailed information about the biometric checks performed, such as liveness checks and face verification, along with the results and any relevant metadata.

**Example Successful Response:** 200: **OK**

A successful API response (usually `0840 - match` and `0841 - no match`) follows the following structure:

```json
{
  "code": "0840",
  "created_at": "2021-08-01T12:00:00Z",
  "job_type": "smart_selfie_compare",
  "message": "Match",
  "job_id": "123456",
  "user_id": "user-12345602--234r",
  "partner_id": "123",
  "partner_params": {
    "job_id": "job-1234-9876",
    "user_id": "user-12345602--234r"
  },
  "updated_at": "2021-08-01T12:00:00Z",
  "status": "approved"
}
```

**Sample Failed Response 400**: **Bad Request**

*Trying to use a job\_id in partner\_params that has already been used*

```json
{
  "error": "Job already exists. Did you mean to set the retry flag to true?",
  "code": "2215"
}
```

####

#### A successful callback response as the following structure

```json

 {
    "ResultCode": "Code indicating the result",
    "ResultText": "Description of the result",
    "IsFinalResult": "true",
    ...additional fields
  }
```

#### Validations

* We perform field validations to ensure all required fields are parsed in the form.

```
{
    "code": "2413",
    "error": "selfie_image is required.",
    "success": false
}
```

* For internal server errors we return the error

```json
{
  "code": "2201",
  "error": "System Error",
  "success": false
}
```

#### Result Codes and Result Texts

Result codes details what the current (or final) result of a job is. Result Codes for all jobs fall into one of three categories:

1. **Matched (or Pass)**\
   This means that all applicable Actions passed and the overall job was approved.
2. **No Match (or Fail)**\
   This means that one or more of the applicable Actions for job failed, and thus, the overall job was rejected according to Smile ID standards.

**Specific Result Codes and Texts**

| Code | Text                                                                          | Description                                                           | Category |
| ---- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------- | -------- |
| 0001 | Data Invalid                                                                  | One of the required input is invalid.                                 |          |
| 0001 | System Error                                                                  | An unknown system error occurred while processing the job.            |          |
| 0840 | Face Match                                                                    | Comparison between the images matched.                                | Approved |
| 0841 | No Match - - No Face Match                                                    | Images did not match and therefore job was rejected.                  | Rejected |
| 0941 | No Match - The compared images are identical.                                 | The comparison image and selfie image are identical or the same image | Rejected |
| 0941 | No Match - No clear face was found in the selfie image. (1st image - selfie). | There were issues with the `selfie_image`                             | Rejected |

**General Failures Result Codes and Texts**

This means no further processing is possible on the job. General failures occur when a job could not be submitted due to a logical/technical issue. These jobs do not show up in the portal and do not have a Smile Job ID.

{% hint style="info" %}
Prefix for error codes may also be **`23xx`** or **`24xx`**
{% endhint %}

<table><thead><tr><th width="187">Code</th><th>Text</th><th>Description</th></tr></thead><tbody><tr><td>2201</td><td>System Error</td><td></td></tr><tr><td>2204</td><td>Error - A parameter is of the wrong data type</td><td>The format of one of the request values was wrong. Please check request values for this product.</td></tr><tr><td>2205</td><td>Error - You are not authorized to do that</td><td>An invalid signature was used to sign the request. Read more on how to troubleshoot this error here.</td></tr><tr><td>2209</td><td>Wrong job type. This user is already enrolled.</td><td>This user is already enrolled. use a unique <code>user Id</code> or <code>allow_new_enroll</code></td></tr><tr><td>2214</td><td>Error - Product not activated for this account</td><td>Product is deactivated on your account. Contact support to activate the product.</td></tr><tr><td>2215</td><td>Error - Job already exists for <code>job_id</code></td><td>An existing job_id was inputted. Enter a unique job id.</td></tr><tr><td>2220</td><td>Error - Production is not enabled for this account</td><td>You have not completed your KYC. Please complete your KYC with Smile ID.</td></tr><tr><td>2413</td><td>Inputs submitted are incorrect</td><td>There are errors with the required inputs eg. Liveness images or comparison images</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://legacy-docs.usesmileid.com/products/for-individuals-kyc/smartselfie-tm-compare.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
