Integration guide

AI Tools

Digital ID Match is a service that allows a business to check whether one of its users (new or existing) has a Yoti ID account by sending their unique attributes to our API.

Yoti will provide a response indicating whether the user has a Yoti Digital ID app account with a verified ID. If the user has such an account, Yoti will allow the relying party to securely request that information through a Yoti QR share.

Users will receive a push notification on their phone that a search has been carried out. We will also send a POST notification to an endpoint that you specify in your request.

Important

You must inform the user that you are carrying out this search. Users are able to opt out of the search from within their Digital ID account.

To perform the search, you must have an active Yoti service generated through the Hub.

Request Access

To use Digital ID Match, the service needs to be enabled for your organisation by the Yoti team. Please contact your account manager or our support team to request access.

POST https://api.yoti.com/did/v2/matches

SDK integration

You will need to ensure the latest version of the Yoti backend SDK is installed.

// Get the Yoti Node SDK library via the NPM registry npm install yoti
// If you are using Maven, add the following dependency: <dependency> <groupId>com.yoti</groupId> <artifactId>yoti-sdk-api</artifactId> <version>3.11.0</version> </dependency> // If you are using Gradle, add the following dependency: compile group: 'com.yoti', name: 'yoti-sdk-api', version: '3.11.0'
// Get the Yoti PHP SDK library via a Composer package composer require yoti/yoti-php-sdk
# Get the Yoti Python SDK library pip install yoti
// To install the Yoti NuGet package, you need to install NuGet Package Manager. After that, enter the following command in the console: Install-Package Yoti // For other installation methods, see https://www.nuget.org/packages/Yoti
// Simply add this as an import: import "github.com/getyoti/yoti-go-sdk/v3" // Or add the following line to your go.mod file require github.com/getyoti/yoti-go-sdk/v3 v3.14.0

Once you have added the Yoti SDK to your project, the check can be performed as shown in the code snippet below:

const yoti = require("yoti"); const fs = require("fs"); const sdkId = "YOUR_SDK_ID"; const pem = fs.readFileSync("path-to-pem-file"); const body = {JSON_BODY}; //see below const request = new yoti.RequestBuilder() .withBaseUrl("https://api.yoti.com/did") .withPemString(pem) .withEndpoint("/v2/matches") .withPayload(new yoti.Payload(body)) .withMethod("POST") .withHeader("X-Yoti-Auth-Id", sdkId) .build();
byte[] JSON_BODY = ... //see below try { SignedRequest signedRequest = SignedRequestBuilder.newInstance() .withKeyPair("<YOTI_KEY_FILE_PATH>") .withBaseUrl("https://api.yoti.com/did") .withEndpoint("/v2/matches") .withPayload(JSON_BODY) .withHttpMethod("POST") .withHeader("X-Yoti-Auth-Id", "<YOTI_CLIENT_SDK_ID>") .build(); YourPojo yourPojo = signedRequest.execute(YourPojo.class); } catch (GeneralSecurityException | URISyntaxException | IOException | ResourceException ex) { ex.printStackTrace(); }
<?php use Yoti\Http\RequestBuilder; use Yoti\Http\Payload; $JSON_BODY = [ ... //see below ]; $request = (new RequestBuilder()) ->withBaseUrl('https://api.yoti.com/did') ->withPemFilePath('<YOTI_KEY_FILE_PATH>') ->withEndpoint('/v2/matches') ->withPayload(Payload::fromJsonData(JSON_BODY)) ->withHeader('X-Yoti-Auth-Id', '<YOTI_CLIENT_SDK_ID>') ->build() //get Yoti Response ->execute(); // * For JSON data in Version >3 please use Payload::fromJsonData(JSON_BODY)
from yoti_python_sdk.http import SignedRequest, RequestHandler import json import requests def execute(request): response = requests.request( url=request.url, data=request.data, headers=request.headers, method=request.method) return response.content def generate_session(): payload = {} # see below payload_string = json.dumps(payload).encode() signed_request = ( SignedRequest .builder() .with_pem_file("<YOTI_KEY_FILE_PATH>") .with_base_url("https://api.yoti.com/did") .with_endpoint("/v2/matches") .with_http_method("POST") .with_header("X-Yoti-Auth-Id", "<YOTI_CLIENT_SDK_ID>") .with_payload(payload_string) .build() ) # get Yoti response response = signed_request.execute() response_payload = json.loads(response.text)
using System; using System.IO; using System.Net.Http; using System.Text; using Microsoft.AspNetCore.Mvc; using Yoti.Auth.Web; HttpClient httpClient = new HttpClient(); StreamReader privateKeyStream = System.IO.File.OpenText(_pemFilePath); string serializedRequest = Newtonsoft.Json.JsonConvert.SerializeObject(new { JSON_BODY // See below }); byte[] byteContent = Encoding.UTF8.GetBytes(serializedRequest); Uri _baseUrl = new UriBuilder("https", "api.yoti.com", 443, "did").Uri; Yoti.Auth.Web.Request DIDMatchRequest = new RequestBuilder() .WithStreamReader(privateKeyStream) .WithBaseUri(_baseUrl) .WithEndpoint("/v2/matches") .WithHttpMethod(HttpMethod.Post) .WithContent(byteContent) .WithHeader("X-Yoti-Auth-Id", "<YOTI_CLIENT_SDK_ID>") .WithQueryParam("secure", true") .Build(); // Send Request HttpResponseMessage response = DIDMatchRequest.Execute(httpClient).Result;
import ( "io/ioutil" "net/http" "github.com/getyoti/yoti-go-sdk/v2/requests" ) key, _ := ioutil.ReadFile("<YOTI_KEY_FILE_PATH>") // Create request request, _ := requests.SignedRequest{ HTTPMethod: http.MethodPost, BaseURL: "https://api.yoti.com/did", Endpoint: "/v2/matches", Headers: map[string][]string{ "Content-Type": {"application/json"}, "Accept": {"application/json"} "X-Yoti-Auth-Key": {"<YOTI_CLIENT_SDK_ID>"}, }, Body: func(data []byte, _ error) []byte { return data }(json.Marshal(jsonobj{ data }, // see below })), }.WithPemFile(key).Request() //get Yoti response response, _ := http.DefaultClient.Do(request)

Request body

{ "attributes": [ { "name": "PHONE", "value": "++447444 444 444" }, ... ], "notification": { // required "url": "https:/example.com/notification?example=query-param", "method": "POST", "verifyTls": true, "headers": { "ANY-HTTP-HEADER": "the-header-value", "ANOTHER-HTTP-HEADER": "another-header-value" } }, "metadata": true }

Key

Required

Description

Example Value

attributes

Yes

An array of attributes to match the user against.

melissa.peterson@yoti.com +447444444444

notification

Yes

If the user indicates within the app that the search was not triggered/opted in by them. You can specify any headers needed.


url

Yes

The URL of your notification endpoint. Include any query parameters here.

https://yoti.com

method

Yes

The API method for the notification. Default value is POST

POST

verifyTls

No

Confirms that your notification endpoint needs TLS verification.

true - Boolean

headers

No

Any HTTP headers for your notification endpoint.


metadata

No

Whether to include additional information related to the matched account(s)

⚠️ Note: Even if requested, metadata will only be included in the response if the user consented for it to be included

true - Boolean

Attributes

There are many different attributes that can be matched against. You can include multiple attributes in a search

Attribute

Description

Value

EMAIL

The user's email address

melissa.peterson@yoti.com

PHONE

The user's phone number - this must include the country code

+447444444444

DOB

The user's Date of Birth - this must be in yyyy-mm-dd format

2000-01-01

FULL_NAME

Full name as it appears on the user's ID document

Melissa Peterson

POST_CODE

Post code from the user's UK address

EC3N 1RE

DOC_NUMBER

The document number from the user's ID document

0123456789

DOC_ISSUER_COUNTRY

The issuing country of the user's ID Document, this must be the ISO 3-letter country code as specified here

GBR

DOC_TYPE

The document type

PASSPORT

These must be used in specified sets

  • Set #0 - Phone

  • Set #1 - Email

  • Set #2 - Phone + Full Name + DOB

  • Set #3 - Email + Full Name + DOB

  • Set #4 - Full name + DOB + Postcode

  • Set #5 - doc type + issuing country + doc number

  • Set #6 - Full name + DOB + doc number

Response

A successful search will return a 201 response, which will include the transaction ID and the attributes/attribute sets that matched.

Any attributes that do not match will not be returned in the response.

If no attributes match, then a 204 No Content response will be returned

{ "matches": [ { "id": "VisRarSFaZG1x5rYTssgS6FswgOHgH77XcSuI7SYFC601YCp88DWt9jjFwOUKZA6", "product": "YOTI", //Or POST_OFFICE "verified": true, "results": [ { "attributes": [ "PHONE" ], "result": "MATCHED" }, { "attributes": [ "EMAIL" ], "result": "MATCHED" }, { "attributes": [ "PHONE", "FULL_NAME", "DOB" ], "result": "MATCHED" }, { "attributes": [ "EMAIL", "FULL_NAME", "DOB" ], "result": "MATCHED" }, { "attributes": [ "FULL_NAME", "DOB", "POST_CODE" ], "result": "MATCHED" }, { "attributes": [ "DOC_NUMBER", "DOC_ISSUER_COUNTRY", "DOC_TYPE" ], "result": "MATCHED" }, { "attributes": [ "FULL_NAME", "DOB", "DOC_NUMBER" ], "result": "MATCHED" } ], "metadata": { "account_created": 5, "id_document_count": 2, "first_nfc_passport_added": 2, "first_id_document_added": 4, "successful_gpg45_identity_profile_share": true } } ] }
{ "statusCode": 204, "headers": { "date": "Mon, 01 Jan 2026 00:00:00 GMT", "server": "yoti-edge-proxy", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "x-request-id": "1beaad0ea3d46e0a3681905208e5b2b2", "connection": "close" }, "data": null }
{ "id": "Yzt0sbVOSauDWPwMQvumjQ", "status": 400, "error": "INVALID_PAYLOAD", "message": "An error message from the server" }
{ "id": "Yzt0sbVOSauDWPwMQvumjQ", "status": 500, "error": "FAILED_DIGITAL_ID_MATCH", "message": "An error message from the server" }
Transaction ID

You should record this ID and securely store it together with the searched email address or phone number. If a user reports on their Digital ID app that the search was not triggered by them, you can cross-reference this information with the webhook notification (detailed below).

Field

Description

Example

id

transaction ID for the search

VisRarSFaZG1x5rYTssgS6FswgOHgH77XcSuI7SYFC601YCp88DWt9jjFwOUKZA6

product

The digital ID product that returns a match

Yoti

verified

Will return match if the Digital ID account has a verified ID

true

attributes

The attribute names requested

PHONE

result

Confirmation if the specified attribute matches

true

Metadata

Details on the user's account


Status

Response

201

Created

204

No match found

400

Bad Request

500

Server Error

Notifications

Push Notification

When performing the search, if the user has a Yoti Digital ID account, they will receive a push notification informing them that the search has taken place. This will also appear in their Activity tab. They will then have the option to confirm whether or not they agree to this.

Example:



The Company name will be the external name of your Yoti application used for performing the match. The Company URL will be the URL in the application settings. See here for information on the application set up.

Webhook Notification

Within the body, you must specify an endpoint for a POST notification. This notification is sent to your backend when a user receives the push notification to their app account and indicates that it is not them.

{ "specversion": "1.0", "id": "Y2el8YXnCTN6d2xa8ENADdKkE21EdNK-_CuSZrkmdHA4UdqsSD2mAXuCwLlZmZDw", "type": "com.yoti.connect.event.did.not-me", "source": "urn:yoti:connect:did", "time": "2025-05-27T12:55:04.199Z" }

Any webhook notification sent via our Digital ID service will have the same payload as defined by Cloud Events specification.

Value

Details

specversion

Version number of the Events Spec

id

The unique transaction ID from the initial response

type

Yoti notification type

source

Yoti service sending the notification

time

The time the user confirmed it wasn't them in UTC.