Integration guide

AI Tools

After completing the Yoti onboarding, you will need to complete authentication for the API by using the Yoti SDK to simplify the process.

SDK Integration

Yoti backend SDKs are available via popular dependency management systems.

npm install -S -E yoti
// If you are using Maven, add the following dependency: <dependency> <groupId>com.yoti</groupId> <artifactId>yoti-sdk-api</artifactId> <version>4.1.0</version> </dependency> // If you are using Gradle, add the following dependency: compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.1.0'
// Get the Yoti PHP SDK library via a Composer package composer require yoti/yoti-php-sdk
pip install yoti
// To install the Yoti NuGet package you will need to install NuGet. // To import the latest Yoti SDK into your project, enter the following // command from NuGet Package Manager Console in Visual Studio: 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 // Or you can run the following command in your terminal: go get github.com/getyoti/yoti-go-sdk/v3

Endpoint

Description

https://api.yoti.com/ai/v1/antispoofing

Use Yoti's anti-spoofing check as a standalone product.

Once you have added the Yoti SDK dependency to your project, you can use it to build and send your request.

Parameter

Description

img

Base64 encoded image.

metadata

(optional) Device used to send the request (can be a string of unknown, laptop, mobile or any value).

secure

Secure information required by Secure Image Capture (SICAP) that certifies the image was not modified. The Yoti Face Capture Module provides this and shouldn't be edited.

See the code snippets below for examples.

const PATHS = { LIVENESS: '/antispoofing', }; const data = { "img": "base64_image", "metadata": { "device": "mobile" // or laptop }, "secure": { "version": "<module version>", "token": "<session jwt>", "signature": "<payload>", "verification": "<verification_data>" } }; const request = new RequestBuilder() .withBaseUrl('https://api.yoti.com/ai/v1') .withPemFilePath('<YOTI_KEY_FILE_PATH>') .withEndpoint(PATHS.LIVENESS) .withPayload(new Payload(data)) .withMethod('POST') .withHeader('X-Yoti-Auth-Id', '<YOTI_CLIENT_SDK_ID>') .withQueryParam('secure', true) .build();
import java.io.File; import org.json.JSONObject; import com.yoti.api.client.spi.remote.call.SignedRequest; import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.SignedRequestResponse; import com.yoti.api.client.KeyPairSource; import com.yoti.api.client.spi.remote.KeyStreamVisitor; import static com.yoti.api.client.FileKeyPairSource.fromFile; private final KeyPairSource fileKeyPairSource; private final java.security.KeyPair keyPair; String LIVENESS = "/antispoofing"; this.fileKeyPairSource = fromFile(new File("<PEM_FILE_PATH>")); this.keyPair = fileKeyPairSource.getFromStream(new KeyStreamVisitor()); JSONObject body = new JSONObject(); body.put("img", requestPayload.get("img")); body.put("metadata", requestPayload.get("metadata")); // Optional, but recommended body.put("secure", requestPayload.get("secure")); byte[] payload = body.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8); SignedRequestBuilderFactory signedRequestBuilderFactory = new SignedRequestBuilderFactory(); SignedRequest signedRequest = signedRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl("https://api.yoti.com/ai/v1/") .withEndpoint(LIVENESS) .withHttpMethod("POST") .withHeader("X-Yoti-Auth-Id", "<YOTI_CLIENT_SDK_ID>") .withQueryParameter("secure", true) .withPayload(payload) .build(); SignedRequestResponse response = signedRequest.execute(); int statusCode = response.getResponseCode(); byte[] responseBody = response.getResponseBody(); Map<String, List<String>> headers = response.getResponseHeaders();
<?php use Yoti\Http\RequestBuilder; use Yoti\Http\Payload; $payload = [ "img" => "base64_image", "metadata" => ["device" => "mobile"], // or laptop "secure" => [ "version" => "<module version>", "token" => "<session jwt>", "signature" => "<payload>", "verification" => "<verification_data"> ], ]; $request = (new RequestBuilder()) ->withBaseUrl('https://api.yoti.com/ai/v1') ->withPemFilePath('<YOTI_KEY_FILE_PATH>') ->withEndpoint('/antispoofing') ->withPayload(Payload::fromJsonData($payload)) // For version < 3, use ->withPayload(new Payload($payload)) ->withMethod('POST') ->withHeader('X-Yoti-Auth-Id', '<YOTI_CLIENT_SDK_ID>') ->withQueryParam('secure', true) ->build(); // Execute request $response = $request->execute(); // Get response body $body = $response->getBody();
from yoti_python_sdk.http import SignedRequest, RequestHandler import json import requests def yoti_age_estimation(): data = { "img": "base64_image", "metadata": { "device": "mobile" # or laptop }, "secure": { "version": "<module version>", "token": "<session jwt>", "signature": "<payload>", "verification": "<verification_data>" } } payload_string = json.dumps(data).encode() signed_request = ( SignedRequest .builder() .with_pem_file("<YOTI_KEY_FILE_PATH>") .with_base_url("https://api.yoti.com/ai/v1") .with_endpoint("/antispoofing") .with_http_method("POST") .with_header("X-Yoti-Auth-Id", "<YOTI_CLIENT_SDK_ID>") .with_param("secure", True) .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); var metadata = new { device = "mobile", // or laptop }; var secure = new { version = "<module version>", token = "<session jwt>", signature = "<payload>", verification = "<verification_data>" }; var bodyObj = new { img = _base64Face, metadata = metadata, secure = secure }; string serializedRequest = Newtonsoft.Json.JsonConvert.SerializeObject(bodyObj); byte[] byteContent = Encoding.UTF8.GetBytes(serializedRequest); Uri _baseUrl = new UriBuilder("https", "api.yoti.com", 443, "ai/v1").Uri; Yoti.Auth.Web.Request ageScanRequest = new RequestBuilder() .WithStreamReader(privateKeyStream) .WithBaseUri(_baseUrl) .WithEndpoint("/antispoofing") .WithHttpMethod(HttpMethod.Post) .WithContent(byteContent) .WithHeader("X-Yoti-Auth-Id", _clientSdkId) .Build(); HttpResponseMessage response = ageScanRequest.Execute(httpClient).Result;
import ( "io/ioutil" "net/http" "github.com/getyoti/yoti-go-sdk/v3/requests" ) key, _ := ioutil.ReadFile("<YOTI_KEY_FILE_PATH>") imageBase64 := base64.StdEncoding.EncodeToString("<base64_image>") metadata := map[string]interface{}{ "device":"mobile" } secure := map[string]interface{}{ "version":"<module_version>", "token":"<session jwt>", "signature":"<payload>", "verification":"<verification_data>" } bodyObj := map[string]interface{}{ "img": imageBase64, "metadata": metadata, "secure": secure, } payload, _ := json.Marshal(bodyObj) // Create session request,_ := requests.SignedRequest{ HTTPMethod: http.MethodPost, BaseURL: "https://api.yoti.com/ai/v1", Endpoint: "/antispoofing", Headers: map[string][]string{ "Content-Type": {"application/img"}, "Accept": {"application/img"}, "X-Yoti-Auth-Id":{"<YOTI_CLIENT_SDK_ID>"}, }, Body: payload, }.WithPemFile(key).Request() //get Yoti response response, _ := http.DefaultClient.Do(request)

Example payload

{ "img": "/9j/4AAQSkZJRgABAgAAAQABAAD/2wAcHNXCKigjEaYH51Me1Zy1Za0P/Z....", "metadata": { "device": "mobile" // or laptop }, "secure": { "version": "<module_version>", "token": "<session_token>", "signature": "<result_signature>", "verification": "<verification_data>" } }

This endpoint will return an anti-spoofing result.

{ "prediction": "real" // or fake }

Response

Explained

Prediction - real

Yoti has detected a real user.

Prediction - fake

Yoti has detected a spoof attempt.

Help If integrating into a non-browser client, we recommend getting in touch with our team for additional support.

Error codes

Error code

Error

Description

404

APP_NOT_FOUND

Application app_id not found.

401

INVALID_X_YOTI_AUTH_ID

  • X-Yoti-Auth-Id__header not provided.

  • auth id is not a valid uuid.

400

INVALID_APP_ID

Application id cannot be empty.

400

INVALID_PUBLIC_KEY

Application public key cannot be empty.

403

DISABLED_APP_STATE

Application must be enabled.

400

INVALID_ORG_ID

Organisation id cannot be empty.

400

INVALID_BILLING_SOURCE_ID

Application billing source id cannot be empty.

404

ORG_NOT_FOUND

Organisation org_id not found.

401

INVALID_YOTI_AUTH_DIGEST

  • X-Yoti-Auth-Digest header is missing.

  • X-Yoti-Auth-Digest is not base64 encoded.

401

INVALID_NONCE

  • Nonce is missing. nonce parameter is mandatory

  • Provided nonce is not a valid uuid.

401

INVALID_TIMESTAMP

  • Timestamp is missing. timestamp parameter is mandatory.

  • Provided timestamp is not a valid unix timestamp.

401

INVALID_PUBLIC_KEY_ENCODING

Failed to load public key. key is not der encoded.

401

UNSUPPORTED_ALGORITHM

Serialised key is of a type that is not supported by the backend.

401

INVALID_SIGNATURE

Failed to verify signature.

403

INVALID_ORG_STATUS

Organisation has an invalid status

404

INVALID_METADATA_DEVICE

Invalid device metadata provided.

400

INVALID_BODY_ENCODING

The request body should be a valid JSON.

404

INVALID_ENDPOINT

The endpoint request is invalid.

413

PAYLOAD_TOO_LARGE

Payload too large, the maximum size is 2MB**.**

400

IMAGE_NOT_PROVIDED

Image has not been provided.

400

INVALID_B64_IMAGE

Cannot read the base64 image.

400

UNSUPPORTED_IMAGE_FORMAT

Image format not supported. Please use JPEGs (95 to 100 quality) and PNGs.

400

IMAGE_SIZE_TOO_BIG

Image size too big, the maximum size is 1.5MB.

400

IMAGE_SIZE_TOO_SMALL

Image size too small, the minimum size is 50KB.

400

MIN_HEIGHT

The image height is incorrect. Image minimum height required is 300 pixels.

400

MAX_HEIGHT

The image height is incorrect. Image maximum height required is 2000 pixels.

400

MIN_WIDTH

The image width is incorrect. Image minimum width required is 300 pixels.

400

MAX_WIDTH

The image width is incorrect. Image maximum width required is 2000 pixels.

400

MIN_PIXELS

To process the image the minimum number of pixels required is 90,000 pixels.

400

MAX_PIXELS

To process the image the maximum number of pixels required is 2,100,000 pixels.

400

IMAGE_WRONG_CHANNELS

Missing colour channel, the input image must be RGB or RGBA.

400

IMAGE_GRAYSCALE_NOT_SUPPORTED

Grayscale images not supported.

503

SERVICE_UNAVAILABLE

The service is temporarily unavailable.

400

FACE_NOT_FOUND

No faces in the image provided.

400

MULTIPLE_FACES

Please only show one face.

400

FACE_BOX_TOO_SMALL

The face in the image provided is too small.

400

FACE_TO_IMAGE_RATIO_TOO_LOW

Face ratio is lower than the minimum ratio.

400

FACE_TO_IMAGE_RATIO_TOO_HIGH

Face ratio is bigger than the maximum ratio.

400

INSUFFICIENT_AREA_AROUND_THE_FACE

Insufficient area around the face in the image provided.

400

IMAGE_TOO_BRIGHT

Image too bright.

400

IMAGE_TOO_DARK

Image too dark.

400

INVALID_LEVEL_OF_ASSURANCE

Invalid antispoofing level of assurance provided.

400

INVALID_REQUEST_BODY

Request body is invalid, '-' field is invalid.

400

INVALID_IMG_VALIDATION_LEVEL

The image validation level is invalid.

401

UNAUTHORIZED

The X-Yoti-Auth-Id provided isn't authorized to access this resource.

500

UNSPECIFIED_ERROR

An internal server error occurred.