Customer Letter

Here we will show you how to generate the Post Office in branch verification customer letter which contains;

  • Applicant information

  • List of documents

  • Branch address

  • Further information.

  • A QR code that the person in branch will be required to scan.

Fetch session config

This endpoint will retrieve the session configuration, and also provide the requirement ID to be used for the instructions. This will be in a UUID format per document requested, and can be found in the required_resources array per document.

GET https://api.yoti.com/idverify/v1/sessions/{sessionId}/configuration

SDK Example:

const { RequestBuilder} = require("yoti");

const request = new RequestBuilder()
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withPemFilePath("<YOTI_KEY_FILE_PATH>") // file path to PEM file
.withEndpoint("/sessions/<sessionId>/configuration")
.withMethod("GET")
.withQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();

// get Yoti response
const response = await request.execute();
<?php

use Yoti\Http\RequestBuilder;
use Yoti\Http\Payload;

$request = (new RequestBuilder())
->withBaseUrl('https://api.yoti.com/idverify/v1')
->withPemFilePath('<YOTI_KEY_FILE_PATH>')
->withEndpoint('/sessions/<sessionId>/configuration')
->withMethod('GET')
->withQueryParam('sdkId', '<YOTI_CLIENT_SDK_ID>')
->build()
//get Yoti Response
->execute();
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 get_session():

signed_request = (
SignedRequest
.builder()
.with_pem_file("<YOTI_KEY_FILE_PATH>")
.with_base_url("https://api.yoti.com/idverify/v1")
.with_endpoint("/sessions/<sessionId>/configuration")
.with_http_method("GET")
.with_param("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build()
)

response = signed_request.execute()
response_payload = json.loads(response.text)
byte[] payload = ...

try {
SignedRequest signedRequest = SignedRequestBuilder.newInstance()
.withKeyPair(<YOTI_KEY_FILE_PATH>)
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withEndpoint("/sessions/<SESSION_ID>/configuration")
.withHttpMethod("GET")
.withQueryParameter("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();

YourPojo yourPojo = signedRequest.execute(YourPojo.class);

} catch (GeneralSecurityException | URISyntaxException | IOException | ResourceException ex) {
ex.printStackTrace();
}
import (
"io/ioutil"
"net/http"
"github.com/getyoti/yoti-go-sdk/v2/requests"
)

sdkID := "<YOTI_CLIENT_SDK_ID>";
key, _ := ioutil.ReadFile("<YOTI_KEY_FILE_PATH>")
// Create session
sessionRequest, _ := requests.SignedRequest{
HTTPMethod: http.MethodGet,
BaseURL: "https://api.yoti.com/idverify/v1",
Endpoint: "/sessions/<SESSION_ID>/configuration",
Params: map[string]string{
"sdkId": sdkID,
},
Headers: map[string][]string{
"Content-Type": {"application/json"},
"Accept": {"application/json"},
},
}.WithPemFile(key).Request()

//get Yoti response
sessionResponse, _ := http.DefaultClient.Do(sessionRequest)
// Coming Soon

Example Response

{…}

Error Response

// 400 response
{
"code": "MALFORMED_REQUEST",
"errors": [
{
"property": "header.X-Yoti-Auth-Token",
"message": "must not be null or empty"
}
]
}

Error code

Description

400

malformed request

401

unauthorised request, wrong key used

404

no session found matching the sessionId provided

409

cannot begin this session until integrator provides all required resources

503

service is unavailable

Generate Customer Letter

This endpoint will generate the letter that the applicant needs to complete the IBV session.

PUT https://api.yoti.com/idverify/v1/sessions/{sessionId}/instructions

SDK Example

const { RequestBuilder} = require("yoti");

const request = new RequestBuilder()
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withPemFilePath("<YOTI_KEY_FILE_PATH>") // file path to PEM file
.withEndpoint("/sessions/<sessionId>/instructions")
.withPayload(new Payload(INSTRUCTIONS_OBJ))
.withMethod("PUT")
.withQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();

// get Yoti response
const response = await request.execute();
<?php

use Yoti\Http\RequestBuilder;
use Yoti\Http\Payload;

$request = (new RequestBuilder())
->withBaseUrl('https://api.yoti.com/idverify/v1')
->withPemFilePath('<YOTI_KEY_FILE_PATH>')
->withEndpoint('/sessions/<sessionId>/instructions')
->withMethod('PUT')
->withPayload(Payload::fromJsonData($payload))
->withQueryParam('sdkId', '<YOTI_CLIENT_SDK_ID>')
->build()
//get Yoti Response
->execute();
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 get_session():
payload = {} # payload
payload_string = json.dumps(payload).encode()

signed_request = (
SignedRequest
.builder()
.with_pem_file("<YOTI_KEY_FILE_PATH>")
.with_base_url("https://api.yoti.com/idverify/v1")
.with_endpoint("/sessions/<sessionId>/instructions")
.with_http_method("PUT")
.with_payload(payload_string)
.with_param("sdkId", "<YOTI_CLIENT_SDK_ID>")
byte[] INSTRUCTIONS_OBJ = ...

try {
SignedRequest signedRequest = SignedRequestBuilder.newInstance()
.withKeyPair(<YOTI_KEY_FILE_PATH>)
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withEndpoint("/sessions/<sessionID>/instructions")
.withPayload(INSTRUCTIONS_OBJ)
.withHttpMethod("PUT")
.withQueryParameter("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();

YourPojo yourPojo = signedRequest.execute(YourPojo.class);

} catch (GeneralSecurityException | URISyntaxException | IOException | ResourceException ex) {
ex.printStackTrace();
}
import (
"io/ioutil"
"net/http"
"github.com/getyoti/yoti-go-sdk/v2/requests"
)

key, _ := ioutil.ReadFile("<YOTI_KEY_FILE_PATH>")
// Create session
request, _ := requests.SignedRequest{
HTTPMethod: http.MethodPut,
BaseURL: "https://api.yoti.com/idverify/v1",
Endpoint: "/sessions/<sessionId>/instructions",
Params: map[string]string{
"sdkId": "<YOTI_CLIENT_SDK_ID>"
},
Headers: map[string][]string{
"Content-Type": {"application/json"},
"Accept": {"application/json"}
},
Body: func(data []byte, _ error) []byte {
return data
}(json.Marshal(jsonobj{ data },
})),
// Coming soon

Example

See below for a complete payload. This will just return a null body.

{
"contact_profile": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@gmail.com"
},
"documents": [
{
"requirement_id": "someIdDocumentRequirementId",
"document": {
"type": "ID_DOCUMENT",
"country_code": "GBR",
"document_type": "PASSPORT"
}
},
{
"requirement_id": "someSupplementaryDocumentRequirementId",
"document": {
"type": "SUPPLEMENTARY_DOCUMENT",
"country_code": "GBR",
"document_type": "UTILITY_BILL"
}
}
],
"branch": {
"type": "UK_POST_OFFICE",
"fad_code": "12345678"
}

Error Response

//400 response
{
"code": "PAYLOAD_VALIDATION",
"message": "There were errors validating the payload",
"errors": [
{
"property": "The JSON property name",
"message": "The error message associated with the property"
}
]
}

Error code

Description

400

payload validation error

401

unauthorised request, wrong key used

404

the referenced application does not exist

409

the session has expired

500

internal server error

503

service is unavailable


Retrieving Customer Letter

This endpoint is used to pull the generated letter in a PDF format, which you can then send to the applicant.

GET https://api.yoti.com/idverify/v1/sessions/{sessionId}/instructions/pdf

SDK Example

const fs = require('fs');
const { RequestBuilder } = require("yoti");

const request = new RequestBuilder()
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withPemFilePath("<YOTI_KEY_FILE_PATH>") // file path to PEM file
.withEndpoint("/sessions/<sessionId>/instructions/pdf")
.withMethod("GET")
.withQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();

// get Yoti response, buffer set to true for execute
const response = await request.execute(true);

// get parsed response
const instructions = response.getParsedResponse();

// Decode instructions octet stream to base64
const base64 = instructions.toString('base64');

// Convert base64 to pdf buffer
const pdf = Buffer.from(base64, 'base64');
<?php

use Yoti\Http\RequestBuilder;

$request = (new RequestBuilder())
->withBaseUrl('https://api.yoti.com/idverify/v1')
->withPemFilePath('<YOTI_KEY_FILE_PATH>')
->withEndpoint('/sessions/<sessionId>/instructions/pdf')
->withMethod('GET')
->withQueryParam('sdkId', '<YOTI_CLIENT_SDK_ID>')
->build();

// get Yoti Response
$response = $request->execute();

// get parsed response
$instructions = $response->getParsedResponse();

// Decode instructions octet stream to base64
$base64 = base64_encode($instructions);

// Convert base64 to pdf
$pdf = base64_decode($base64);

// Write pdf to file
$fileName = 'instructions.pdf';
file_put_contents($fileName, $pdf);
import base64
from yoti_python_sdk.http import SignedRequest

signed_request = (
SignedRequest.builder()
.with_base_url("https://api.yoti.com/idverify/v1")
.with_pem_file("<YOTI_KEY_FILE_PATH>")
.with_endpoint("/sessions/<sessionId>/instructions/pdf")
.with_http_method("GET")
.with_param("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build()
)

# get Yoti Response
response = signed_request.execute()

# get parsed response
instructions = response.parsed_response

# Decode instructions octet stream to base64
base64_instructions = base64.b64encode(instructions)

# Convert base64 to pdf
pdf = base64.b64decode(base64_instructions)

# Write pdf to file
import org.apache.commons.codec.binary.Base64;
import com.yoti.api.client.spi.remote.call.SignedRequest;
import com.yoti.api.client.spi.remote.call.SignedRequestResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;

SignedRequest signedRequest = SignedRequest.builder()
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withPemContents("PEM_CONTENT")
.withEndpoint("/sessions/<sessionId>/instructions/pdf")
.withHttpMethod("GET")
.withQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();

// get Yoti Response
SignedRequestResponse response = signedRequest.execute();

// get parsed response
byte[] instructions = response.getParsedResponse();

// Decode instructions octet stream to base64
package main

import (
"encoding/base64"
"fmt"
"io"
"net/http"
"os"

"github.com/getyoti/yoti-go-sdk/v3/requests"
)

func main() {
key, _ := os.ReadFile("<YOTI_KEY_FILE_PATH>")

request, _ := requests.SignedRequest{
HTTPMethod: http.MethodGet,
BaseURL: "https://api.yoti.com/idverify/v1",
Endpoint: "/sessions/<sessionId>/instructions/pdf",
Params: map[string]string{"sdkID": "<YOTI_CLIENT_SDK_ID>"},
}.WithPemFile(key).Request()

// Get Yoti response
response, err := http.DefaultClient.Do(request)
if err != nil {
fmt.Println("Error making HTTP request:", err)
return
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Yoti.Auth.Web;

HttpClient _httpClient = new HttpClient();

Request signedRequest = new RequestBuilder()
.WithBaseUri(new Uri("https://api.yoti.com/idverify/v1"))
.WithKeyPair("PEM_CONTENT")
.WithEndpoint("/sessions/<sessionId>/instructions/pdf")
.WithHttpMethod(HttpMethod.Get)
.WithQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.Build();

// get Yoti Response
HttpResponseMessage response = await signedRequest.Execute(_httpClient).ConfigureAwait(false);

// get parsed response
var instructions = await response.Content.ReadAsByteArrayAsync();

// Decode instructions octet stream to base64

PDF Example


Important - The use of the Post Office branded customer letter is mandatory for the In-Branch Verification service.

Error Response

//400 response
{
"code": "PAYLOAD_VALIDATION",
"message": "There were errors validating the payload",
"errors": [
{
"property": "The JSON property name",
"message": "The error message associated with the property"
}
]
}

Error code

Description

400

payload validation error

401

unauthorised request, wrong key used

404

the referenced application does not exist

409

the session has expired

500

internal server error

503

service is unavailable


  Last updated by Saurabh Bansal