Skip to content

Biometric Verifications

Our biometric verification API offers advanced identity confirmation by using unique physical characteristics, like facial features. This ensures precise, secure, and fast identity verification, compliant with AML and KYC regulations, making the process user-friendly and efficient.

Integrating Biometric Verification has three phases:

  • Phase 1: Creating a new verification by sending a verification URL to a client
  • Phase 2: Receiving events (including results) about verifications to your web hook (optional)
  • Phase 3: Downloading verification assets (images, video, PDF) (optional)

A basic integration may only involve phase one; in this case, users can log into our web application to view the verification results. A full integration including phases two and three will see complete verification results returned to your system programmatically, and users do not need to access our web application.

See the below diagram for a graphical representation of the phases:

An image

POST Create a New Biometric Verification


API

Description: Create a new verification / trigger SMS sent to client

Endpoint: POST /api/v2/send_text

Properties:

PropertyRequiredTypeNotes / Description
contact_phonenostringMobile phone number to send SMS message to(assuming the value for communication_method is "sms"). Use international format without “+” symbol. If not provided, verification URL is returned instead of sending SMS.
firstnamenostringFirst name of the person being verified
lastnamenostringLast name of the person being verified
emailyesstringThe email address of the individual in question. The field is required only when subscribed to Fraud Analytics.
referenceyesstringA name to recognise the verification
external_idnostringYour system’s object id. This can also be used to make the link between your system’s entity and our verification
notificationsno[string]An array of type string containing email addresses to send notifications to when the verification process is completed
flow_typenostringOnly relevant to Australian customers; your Account Manager will advise. Possible values are “SIMPLE2” or “VOI2”.
biometric_onlynobooleanDefaults to false. If true, identity data searches are not conducted.
redirect_success_urlnostringHTTPS URL for redirecting the end user after the verification flow is completed
redirect_cancel_urlnostringHTTPS URL for redirecting the end user after the verification flow is cancelled
communication_methodnostringDefaults to 'sms'. If 'link', sms won't be send even if contact_phone is present

Sample Response(sending SMS):

json
{ "transaction_id": "eUmE4voe-L_BRzjG" }

Sample Response(without sending SMS):

json
{ 
    "transaction_id": "c2jYDUbgZsYcr9Dx",
    "start_process_url": "https://integration.aplyid.com/l/c2jYDUbgZsYcr9Dx" 
}

NOTE

We recommend that you save the transaction id we return.

NOTE

You may HTTP redirect your client to the start_process_url for them to complete the verification journey. We recommend that you do this using the handset’s default web browser; Web View is not recommended for our verification journey because it has limitations surrounding JavaScript execution and access to native functionalities (i.e. the camera).

NOTE

Once the user completes the verification journey, we will redirect them to the redirect_success_url you provided.

The redirect_success_url must be an HTTPS URL; deep links or custom URL schemes are not supported. You will need to add the domain to the Allowed domains section of the portal or your request will return an error.

If you are trying to redirect the user back into your native mobile application, you can configure your application to react to the HTTPS URLs that you gave to us; please see Android’s app links or iOS’ universal links.

PUT Resending an SMS


API

Description: Resend an already created verification, to the same or different mobile number

Endpoint: PUT /api/v2/resend_text/:transaction_id

Properties:

PropertyRequiredTypeNotes / Description
contact_phonenostringPhone number to resend the text to. If not specified, we will resend the SMS message to the same number.

NOTE

Transaction ID must exist and the verification must be in the ‘created’ state. We recommend that you save the transaction id we return (it will be different to the original value) and replace the previous transaction id saved in your system.

NOTE

When you request us to resend an SMS, two things happen:

We archive the original verification entity (your web hook will receive an Archive event if enabled)

We create a new verification entity (your web hook will receive a Created event if enabled)

Response body:

json
{ "transaction_id":  "eUmE4voe-L_BRzjG"  }

Receiving events at your web hook

Web Hook Configuration:

Your web hook configuration settings are in the Developer Dashboard. The following basic requirements must be met by your webhook:

  • Use HTTPS
  • Use a supported authentication scheme (Basic, Digest, or Bearer Token)
  • Accept HTTP POST requests from our server

Before saving your web hook, click the Test button to verify the connection; the test will send an HTTP POST to your web hook with the following JSON request body:

json
{
    "message": "Hello from APLYiD! Web Hook Test",
    "event": "test"
}

The test is considered successful if your server responds with a successful HTTP status (i.e. 2xx or 3xx). The test will fail if the HTTP response is unsuccessful (i.e. 4xx or 5xx).

Web Hook Outages and Maintenance:

If your server (hosting your web hook) has a temporary outage, this will not adversely affect your integration. For every event we send to your web hook, we are expecting to receive a successful HTTP response status, i.e., 200 OK.

If we do not receive a successful HTTP response status, we will queue the event to be retried. The event will be retried up to 8 times according to an exponential backoff algorithm with the final attempt occurring approximately 5 hours after the original attempt.

Web Hook Events:

Once your web hook is configured and enabled you will receive events for every Biometric Verification, regardless of whether the verification was created via API or via our web application.

The payload being sent by POST to your web hook is defined as follows:

json
// Basic JSON event structure posted to web hook
{
    "event": "created",
    "reference": "MY_FIRST_VERIFICATION",
    "external_id": "27b438e9-6d02-486a-9860",
    "phone_number": "+6412345678",
    "transaction_id": "_5qKX6G0s595z7Jy",
    "verification": null,
    "message": null,
}
PropertyDescription
eventType of event (see list of all possible events below)
referenceThe reference (friendly name) you provided when creating the verification
external_idThe external_id (your system’s object ID) you provided when creating the verification
phone_numberThe mobile phone number we sent the SMS message to (if applicable) Note: The value will be in international format, now with a leading “+” symbol
transaction_idAPLYiD’s unique identifier for the verification
verificationVerification result. This is only set when the event is completed or updated
messageError message or additional information

APLYiD will notify your system whenever one of the following events occurs on your Biometric Verifications:

EventDescription
createdA new verification has been created and SMS sent (if applicable)
completedA verification has been completed. The results are included in the ‘verification’ JSON property
updatedA verification has been updated. This happens when one of your users makes changes to the verification (i.e. conducts a review, adds notes, edits extracted data) via our web application. You should replace the old result in your system with the new result included in the ‘verification’ JSON property
archivedA verification just got archived. This happens 60 minutes after downloading a PDF report, or once the verification reaches the end of its 7-day lifespan
errorA verification encountered an unexpected error during processing. A notification will be sent to the agent (and any of their managers) to notify them about the failure. If you receive this event, you should consider this verification “dead” and create a new verification instead.
pendingWe could not immediately verify the client’s details (using government and other data sources) because the data source is unavailable. We will keep retrying periodically

Notes on pending events

Government data sources (especially in New Zealand and Australia) are occasionally taken offline for long periods to conduct maintenance. The pending event was introduced to handle this scenario; keeping you informed of the situation.

Following an initial ‘pending’ event, we will periodically retry to verify the client’s details with the data source over a 24 hour window. We will send the pending event again for every unsuccessful attempt. Once successful, you will receive a ‘completed’ event. If not successful within 24 hours, you will receive an ‘error’ event.

Notes on completed / updated events

When the verification is completed or updated, the JSON will include the results in the ‘verification’ property. If the verification is updated, you do not need to re-download video/image assets, as these will not change.

Sample Response

javascript
{
    "message": null,
    "event": "completed",
    "reference": "MY_FIRST_VERIFICATION",
    "external_id": null,
    "phone_number": "+64211234567",
    "transaction_id": "TLAVFwnHc5LAz8bD",
    "verification": {
        "type": "biometric",
        "status": "pass",
        "reviewed": false,
        "capture": {
            "id_document": {
                "front_image": "AWS S3 presigned GET url valid for 15 minutes",
                "back_image": "AWS S3 presigned GET url valid for 15 minutes",
                "front_image_uncropped": "AWS S3 presigned GET url valid for 15 minutes",
                "back_image_uncropped": "AWS S3 presigned GET url valid for 15 minutes",
                "face_image": "AWS S3 presigned GET url valid for 15 minutes"
            },
            "face": {
                "video": "AWS S3 presigned GET url valid for 15 minutes",
                "image_extracted": "AWS S3 presigned GET url valid for 15 minutes"
            }
        },
        "data": {
            "personal": {
                "firstname": "John",
                "middle_name": null,
                "lastname": "Doe",
                "date_of_birth": "02/10/1985"
            },
            "id_document": {
                "country": "NZL",
                "type": "driver_licence",
                "id_number": "DL123456",
                "expiry_date": "09/07/2028",
                "id_version": "123"
            },
            "address": {
                "full": "22 Pollen Street, Grey Lynn, Auckland 1021",
                "address_line_1": "22 Pollen Street",
                "suburb": "Grey Lynn",
                "postcode": "1021",
                "city": "Auckland",
                "country": "NZL"
            }
        },
        "device": {
            "browser": "Safari",
            "geolocation": [
                57.52695194906678,
                -0.08651187930802037
            ],
            "ip": "456.755.51.50",
            "ip_location": [
                57.508499145123,
                -0.12569999694824
            ],
            "isp": "Venus Business Communications Limited",
            "os": "iOS 15",
            "vpn": false,
            "device": "iPhone",
            "loc_distance": 3.400397719392051
        },
        "notes": null,
        "tampering_checks": {
            "overall": true
        },
        "biometrics": {
            "overall": true,
            "details": {
                "face_match": {
                    "overall": true,
                    "left_eye": "Pass",
                    "right_eye": "Pass",
                    "left_brow": "Pass",
                    "right_brow": "Pass",
                    "forehead": "Pass",
                    "middle_forehead": "Pass",
                    "nose": "Pass",
                    "philtrum": "Pass",
                    "mouth": "Pass",
                    "jaw": "Pass",
                    "left_cheek": "Pass",
                    "right_cheek": "Pass"
                },
                "liveness": {
                    "overall": true,
                    "gestures": "PASS",
                    "spoofing": "LOW_RISK",
                    "attempt_count": 1
                }
            }
        },
        "fraud_analytic": {
            "id": 6,
            "fullname": "John Doe",
            "ip_address": "456.755.51.50",
            "contact_phone": "642108754787",
            "email": "john.doe@test.com",
            "address": "22 Pollen Street, Grey Lynn, Auckland, 1021",
            "errors": null,
            "results": {
                "risk_indicators": [
                    {
                        "type": "Identity Network Score",
                        "indicator": "There is a HIGH risk associated with this digital interaction",
                        "score": 0.989,
                        "risk_value": "HIGH"
                    },
                    {
                        "type": "Identity Risk Score",
                        "indicator": "The identity risk score suggests a LOW level of risk for this user",
                        "score": 100,
                        "risk_value": "LOW"
                    },
                    {
                        "type": "IP Risk Score",
                        "indicator": "There is a NEUTRAL risk associated with this IP address",
                        "score": "not-found",
                        "risk_value": "NEUTRAL"
                    }
                ],
                "other_indicators": [
                    {
                        "type": "Phone to Name Match",
                        "value": "match",
                        "risk_value": "LOW"
                    },
                    {
                        "type": "Email to Name Match",
                        "value": "not-found",
                        "risk_value": "NEUTRAL"
                    },
                    {
                        "type": "Address to Name Match",
                        "value": "no-match",
                        "risk_value": "MEDIUM"
                    },
                    {
                        "type": "IP Risk Found",
                        "value": true,
                        "risk_value": "HIGH"
                    }
                ],
                "network_activity": [
                    {
                        "type": "Days since the email was first seen in the network",
                        "value": 0,
                        "risk_value": "HIGH"
                    },
                    {
                        "type": "Days since the phone number was last seen in the network",
                        "value": "not-found",
                        "risk_value": "NEUTRAL"
                    },
                    {
                        "type": "Days since the IP address was last seen in the network",
                        "value": 500,
                        "risk_value": "LOW"
                    }
                ]
            }
        },
        "pep": {
            "overall": true
        },
        "location": {
            "overall": true
        },
        "aply_portal_url": "https://integration.aplyid.com/portal/agent/biometrics/completed/47",
        "result": {
            "overall": true,
            "document_checks": true,
            "biometrics": true,
            "location": true,
            "id_document": true, // Only relevant to NZL/AUS ID documents. All others will be false "pep": true,
            "fullname": true,
            "date_of_birth": true,
            "address": true
        },
        "pdf": "https://integration.aplyid.com/api/v2/biometric/pdf/TLAVFwnHc5LAz8bD.pdf"
    }
}

Different result formats

There are some small differences in the results depending on

  • the type / country of ID document
  • the country of address
  • the suitability of the handset’s camera for capturing video

The tables below highlight these differences:

verification -> data -> id_document

NZL Driver Licence propertiesAUS Driver Licence propertiesGBR Driver Licence propertiesPassport properties
countrycountrycountrycountry
typetypetypetype
id_numberid_numberid_numberid_number
expiry_dateexpiry_dateexpiry_dateexpiry_date
id_versionid_state
card_number

verification -> data -> address

New Zealand AddressAustralian AddressUnited Kingdom Address
countrycountrycountry
address_line_1address_line_1address_line_1
address_line_2address_line_2address_line_2
suburbsuburbsuburb
citystatecity
postcodepostcodepostcode

When completing the APLYiD verification flow some users may do so:

  • using older mobile phones with insufficient video quality
  • using a poor network connection unsuitable for video upload

In these cases, the APLYiD verification flow guides the user to take a selfie photo(s) instead of a video. The selfie is returned in the image_extracted key and the video key will be null.

javascript
"face": {
    "image_extracted": "Selfie photo as an AWS S3 presigned GET url valid for 15 minutes",
    "video": null
}

Tampering checks

By default, you will receive an overall Boolean value for tampering_checks where false indicates suspicion of tampering and true indicates no suspicion.

For advanced users, we can enable an advanced result format which details the result of each individual tampering check; please speak to your Account Manager if you would like this enabled. Please note, enabling this does not change the tampering checks performed, only the result format.

If using the advanced format, please loop over the JSON object and parse the key name (i.e. “card_check”) and value (i.e. true). The key names change based on a variety of factors, so we recommend you implement in a manner that is independent of specific key names.

The below shows an example of an advanced tampering check result, where the key names have been obfuscated:

javascript
"tampering_checks": {
    "overall": false,
    "details": {
        "check_1": true,
        "check_2": false,
        "check_3": true,
        "check_4": false
    }
}

Data Sources

By default, this field is not provided.

For advanced users, we can return a table which details the results of each individual data source; please speak to your Account Manager if you would like this enabled.

If using the table format, the "config" array indicates the data types that we search for while the "rows" array indicates the match results of each of these data types for each data source.

These match results can be:

ResultDescription
MatchSuccessfully matched
No MatchNot matched
Not PresentData is not present on the data source, for example a data source may not hold date of birth information for the individual being verified
Not SearchedHas not been searched, for example if a driver licence number is not provided the data source will not be searched
NAData type is not held by the data source

The data source names change based on a variety of factors, so we recommend you implement in a manner that is independent of specific data source names.

The below shows an example of data sources, where the data source names have been obfuscated:

javascript
"data_sources": {
    "config": [
        {
            "field": "summary_of_data_sources_searched",
            "label": "Summary of data sources searched"
        },
        {
            "field": "name",
            "label": "Name"
        },
        {
            "field": "date_of_birth",
            "label": "Date of Birth"
        },
        {
            "field": "address",
            "label": "Address"
        }
    ],
    "rows": [
        {
            "summary_of_data_sources_searched": "Data Source 01",
            "name": "Match",
            "date_of_birth": "Match",
            "address": "Match"
        },
        {
            "summary_of_data_sources_searched": "Data Source 02",
            "name": "Match",
            "date_of_birth": "Match",
            "address": "Match"
        },
        {
            "summary_of_data_sources_searched": "Data Source 03",
            "name": "Match",
            "date_of_birth": "NA",
            "address": "NoMatch"
        },
        {
            "summary_of_data_sources_searched": "Data Source 04",
            "name": "Match",
            "date_of_birth": "Match",
            "address": "NA"
        },
        {
            "summary_of_data_sources_searched": "Data Source 05",
            "name": "NotSearched",
            "date_of_birth": "NotSearched",
            "address": "NotSearched"
        },
        {
            "summary_of_data_sources_searched": "Data Source 06",
            "name": "NotSearched",
            "date_of_birth": "NotSearched",
            "address": "NotSearched"
        }
    ]
}

Device

This section of the result provides details about the handset used to complete the verification.

  • Geolocation (physical location of handset) may be null if the user did not grant access to their location.
  • Loc_distance is the straight-line distance in kilometres between IP location and Geo location.
  • Loc_distance is not included unless the user granted access to their location.

Fraud Analytics

Our enhanced Biometric Verification product is designed to catch fraud earlier, significantly improving the onboarding process and enabling you to make more informed decisions. With advanced data insights and enhanced risk management, our tool helps you continuously stay ahead of fraudsters.

This feature by default is off, please ask your Account Manager to enable this.

Interpreting the result

When a verification is completed, its status is set to one of the following values depending on the next action required:

StatusDescription
passBiometrics matched and verification of the client’s details was successful . Full name, date of birth and address are verified, ID passed verification (if applicable), tampering checks came back clean and PEP check is clear
reviewSomething needs to be manually checked by one of your agents. It can happen when an address is mismatched, tampering checks comes as a false positive due to poor photo quality or the person being verified fails liveness
failVerification of the client failed . Biometrics didn’t match the person, or we couldn’t verify the data

Please see verification -> results for a more detailed breakdown to understand which checks contributed the overall status.

Conducting Reviews

If the status is review, you should redirect your staff member to our web application using the URL provided at verification -> aply_portal_url. We will require them to log in, review the verification manually and comment their decision in the dedicated form. Once completed, your endpoint will receive an updated event and its status will now be set to “pass” or “fail” depending on the agent’s decision. A “reviewed” flag (verification -> reviewed) is here to let you know the verification status has been decided by an agent.

By default, if a verification requires review, we will not allow the verification to be downloaded as PDF until the review has been completed. If you would like to download PDFs without conducting reviews in our web application, please ask your Account Manager to enable this.

GET Downloading assets (pictures, video, and PDF)


API

Description: Download verification PDF Report

Endpoint: GET /api/v2/biometric/pdf/{transaction_id}.pdf

PLEASE NOTE:

PDFs can only be downloaded once a verification is completed. You must not poll the PDF address or attempt to download the PDF before receiving a completed or updated event at your web hook.

NOTE

The PDF’s URL is also provided in the completed/updated JSON event at verification -> pdf.

Optional features

We have several configurable options for Biometric Verification via API, to tailor the product to your needs. Please enquire about any of the below with your Account Manager to ensure they are suitable for your needs.

Generate a URL instead of an SMS:

Omit the contact_phone from the send_text request to receive a URL instead.

If you want to send contact_phone in the payload but recieve a URL instead, simply set the value of communication_method to "link"

Remove our 0800 number from the SMS:

Ask your Account Manager to configure.

Capture client details but do not verify them:

Set biometric_only to true in the send_text request

Allow PDF report download without conducting review:

Ask your Account Manager to configure

Receive advanced Tampering Check data:

Ask your Account Manager to configure

Receive advanced address data (from address auto-complete):

Ask your Account Manager to configure

Enable Australian Credit Header data:

Ask your Account Manager, approval required

Enable Australian Government Verification of Identity (VOI) flow:

Set flow_type to VOI2 in the send_text request

Examples

js
axios.post('https://integration.aplyid.com/api/v2/send_text', 
{
    reference: 'MY_FIRST_VERIFICATION',
    contact_phone: '64123456789',
    firstname: 'John',
    lastname: 'Doe',
    external_id: '9a3b633f-b739-489a-96ce-24d27a1ea3ba',
    notifications: [ 'bruce@wayne-corporation.com' ]
}, 
{
    headers: {
        'Aply-API-Key': 'zHb4LM9dSBAwiVECjKSoG6Fy',
        'Aply-Secret': 'Uds32eU6hG2MFSMioEdXVGWNVkSnR1A7'
    }
})
.then(response => { 
    // Do some stuff
})
.catch(error => {
    console.log(error.response.data.message)
})
js
// Redirect user to start
axios.post('https://integration.aplyid.com/api/v2/send_text',
{
    reference: 'MY_SECOND_VERIFICATION',
    external_id: '27b438e9-6d02-486a-9860',
    notifications: [ 'bruce@wayne-corporation.com' ],
    redirect_success_url: 'https://yourdomain.com/success?token=27b438e9-6d02-486a-9860', 
    redirect_cancel_url: 'https://yourdomain.com/cancel?token=27b438e9-6d02-486a-9860'
},
{
    headers: {
        'Aply-API-Key': 'zHb4LM9dSBAwiVECjKSoG6Fy', 
        'Aply-Secret': 'Uds32eU6hG2MFSMioEdXVGWNVkSnR1A7'
    }
})
.then(response => { 
    // Do some stuff
})
.catch(error => {
    console.log(error.response.data.message) 
})
js
axios.put('https://integration.aplyid.com/api/v2/resend_text/yy7NhYchoqT1ny9i', 
{
    contact_phone: '64123456789'
}, 
{
    headers: {
        'Aply-API-Key': 'zHb4LM9dSBAwiVECjKSoG6Fy',
        'Aply-Secret': 'Uds32eU6hG2MFSMioEdXVGWNVkSnR1A7'
    }
})
.then(response => { 
    // Do some stuff
})
.catch(error => {
    console.log(error.response.data.message)
})
js
const express = require('express')
const axios = require('axios')
const contentDisposition = require('content-disposition') const fs = require('fs')
const app = express()
const port = 3333
app.use(express.json())
// Configured endpoint to receive events from APLYiD
app.post('/hook_basic', (req, res, next) => {
    const result = req.body;
    // A real implementation should handle all the event types, not just completed
    if (result.event === 'completed') {
        // Getting verification result from transaction const verification = result.verification
        if (!!verification) {
            // Checking that the verification passed or failed. If not, the verification
            // needs to be reviewed first
            if (verification.status === 'pass' || verification.status === 'fail') {
                const pdfUrl = verification.pdf

                const idPictureUrl = verification.capture.id_document.front_image
                // PDF download needs to be authenticated using your API key
                axios.get(pdfUrl, {
                        headers: {
                            'Aply-API-Key': 'RRXHMXPHzQAw46SuBdSZaNFs',
                            'Aply-Secret': 'q97Ffmb3knKEQ7mCB5L8PFRJurTqEzdR'
                        },
                        responseType: 'stream'
                    })
                    .then(res => {
                        // Using contentDisposition to retrieve generated filename from headers
                        const content = contentDisposition.parse(res.headers['content-disposition']) // Writing downloaded PDF to our server's file system res.data.pipe(fs.createWriteStream(content.parameters.filename))
                    })
                    .catch(e => {
                        console.log("Something went wrong downloading pdf")
                    })
                // Verification assets links are AWS S3 presigned GET url. They are only // valid for 15 minutes
                axios.get(idPictureUrl, {
                        responseType: 'stream'
                    })
                    .then(res => {
                        // We are taking a filename from the URL path. But you can use any file name const url = new URL(idPictureUrl) res.data.pipe(fs.createWriteStream(url.pathname.split('/').pop()))
                    })
                    .catch(e => {
                        console.log("Something went wrong downloading id picture")
                    })
            }
        } else {
            console.log('Verification result is empty')
        }
    }
    next()
})
app.listen(port, () => console.log(`Running server on ${port}`))

Error Codes

401 Unauthorized

json
{
  "error_code": "AUTH_FAILED",
  "message": "Bad credentials"
}
// API call not authenticated. Your credentials are wrong or the IP address did not match your IP allow-list

403 Forbidden

json
{
  "error_code" : "FORBIDDEN",
  "message" : "You're not authorized to access this resource"
}
// The credentials you are using do not allow you to perform the action you’re trying to do. This can happen when using an agent’s key and  trying to export a verification they do not have access to.

400 Bad Request

json
{
  "error_code": "CRED_AT_RISK",
  "message": "API keys and secret should never be used together for an AJAX request."
}
// You have tried to create a verification using your key and secret over a Javascript request from a browser e.g. AJAX/XHR request

400 Bad Request

json
{
  "error_code": "SMS_FAIL",
  "message": "SMS couldn't be sent, verify phone number and medium is valid."
}

422 Unprocessable Entity

json
{
  "error_code": "VALIDATION_FAILED",
  "message": "Data validation failure"
}

404 Not Found

json
{
  "error_code": "NOT_FOUND",
  "message": "Verification not found"
}
// The verification you are trying to export couldn’t be found

400 Bad Request

json
{
  "error_code": "ALREADY_ARCHIVED",
  "message": "Verification is archived and data has been erased"
}
// The verification you are trying to export has already been archived and the pdf is no longer available

400 Bad Request

json
{
  "error_code": "NOT_COMPLETED",
  "message": "You can't export a verification that is not completed"
}
// The verification you are trying to export is not completed

422 Unprocessable Entity

json
{
  "error_code": "SYSTEM",
  "message": "Unexpected system error"
}