DocVal Server WebSocket API

Overview DocVal Server – WebSocket API

The Document Validation Server (DocVal server) will directly communicate with the eMRTD ( NFC Chip) of an ICAO Passport. The Communication between the NFC Chip and the DocVal server will be End-to-End encrypted.

The DocVal server is able to read the data (like MRZ Info or Photo of Face) and verify the authenticity and integrity of the data.

If the NFC Chip supports the Active Authentication Protocol or the Chip Authentication Protocol, the DocVal server will additionally be able to verify that the chip was not cloned.

This process is implemented as defined in ICAO Doc9303.

The Result (Data and Check Results) will be posted (Using a HTTP POST Request) to a Result Server.

As the WebSocket Session to the client is closed, all data about a passport will be deleted. The DocVal server is designed to not store any passport data longer than needed.

WebSocket API Endpoint

The Server will access the Chip through a WebSocket Connection.

The client device (which may be an Android Phone or Apple iPhone with NFC capabilities) connects to the WebSocket.

The OVDK Instance of the DocVal Service can be reached via the following url:


If the query parameter return_result is set to true, the result will also be returned to the client device. This is useful if the result should be displayed on the client device.


Starting the Process

To start the process, the client sends a StartMessage to the server. The StartMessage is JSON encoded and sent as a text message to the server:

  "client_id": "YOUR CLIENT ID",
  "validation_id": "cf847daa-a548-4509-bdeb-4edd51aee448",
  "access_key": {
    "can": "153036"
  "nfc_adapter_supports_extended_length": false,
  "platform": "android"
  "client_id": "YOUR CLIENT ID",
  "validation_id": "cf847daa-a548-4509-bdeb-4edd51aee448",
  "access_key": {
    "can": "153036"
  "nfc_adapter_supports_extended_length": true,
  "max_command_bytes": 1024,
  "max_response_bytes": 1024,
  "platform": "ios"
  "client_id": "YOUR CLIENT ID",
  "validation_id": "cf847daa-a548-4509-bdeb-4edd51aee448",
  "access_key": {
    "document_number": "123465789",
    "date_of_birth": "970825",
    "date_of_expiry": "251008"
  "nfc_adapter_supports_extended_length": true,
  "max_command_bytes": 1024,
  "max_response_bytes": 1024,
  "platform": "ios"
  • client_id
    Functions as an API Access key. Is configured by you, if the DocVal Service runs On-Premise. CUSTOMER may use Client ID “YOUR CLIENT ID” with the OVDK Instance of the DocVal Server.
  • validation_id
    A (unique) id from you to identify the verification and to map the result to a user/session. This id will be passed through to the Result Server with the result.
  • access_key
    To Access the chip either the 6 digit “CAN” or the “MRZ Info” is needed. The MRZ Info consists of the Document Number, the Date of Birth and the Date of Expiry. These values will be encoded as in the MRZ of the document, meaning the dates are encoded as “yyMMdd”.
  • nfc_adapter_supports_extended_length
    Whether the NFC Adapter supports extended-length-APDUs. For iPhone devices this will be true. For Android Devices this value can be queried from the IsoDep instance.
  • max_command_bytes
    The maximum number of bytes in a command apdu, the nfc chip is able to process. This field is optional and may be null if the value is unknown to the client.
  • max_response_bytes
    The maximum number of bytes in a response apdu, the server is allowed to request from the nfc chip. This field is optional and may be null if the value is unknown to the client. If provided the session duration is slightly shorter, as the server skips reading the Atr/Info file.
  • platform
    Short string identifying the platform of the client. Use “android” for Android Clients. Use “ios” for iOS Clients.

Communication between the DocVal Server and the NFC Chip

Once the DocVal server received the StartMessage the server sends apdu-commands as binary messages to the client device. The client device needs to pass those binary messages to the chip. The client device then sends the response from the chip as a binary message to the server.

+---------------+       1        +--------------------------+      2       +--------------+
|   Document    |--------------->|      Client Device       |------------->|    eMRTD     |
|  Validation   |                |       (e.g. Phone)       |              |  (NFC Chip)  |
|    Server     |<---------------|                          |<-------------|              |
+---------------+       4        +--------------------------+      3       +--------------+

The Client device functions as a proxy to allow the server and the NFC Chip to communicate.

DocVal Server provides Updates about the Progress

The Server will provide updates about the current status to the client device. These updates will be text messages and contain a JSON.

  "status": "READ_DG1"

The following status messages are to be expected (also in that order):

Status Message Description
"READ_ATR_INFO" Server is reading the ATR/INFO file.
"ACCESS_CONTROL" Server is accessing Chip using the Access Key.
"READ_SOD" Server is reading the SOD file.
"READ_DG14" Server is reading the DG14 file (only if present).
"CHIP_AUTHENTICATION" Server is performing Chip Authentication (only if supported).
"READ_DG15" Server is reading the DG15 file (only if present).
"ACTIVE_AUTHENTICATION" Server is performing Active Authentication (only if supported).
"READ_DG1" Server is reading the DG1 file.
"READ_DG2" Server is reading the DG2 file.
"READ_DG7" Server is reading the DG7 file (only if present).
"READ_DG11" Server is reading the DG11 file (only if present).
"READ_DG12" Server is reading the DG12 file (only if present).
"PASSIVE_AUTHENTICATION" Server is verifying the authenticity and integrity of the data.
"DONE" Process is finished

The server will only attempt to read the ATR/INFO file, if the nfc adapter supports extended-length-APDUs and the max_command_bytes and max_response_bytes in the StartMessage have not been set.

Note that some files (DG14, DG15, DG7, DG11, DG12) are optional and not available on all passports.

Also note that the protocols Active Authentication and Chip Authentication are optional and not supported on all passports.

Result is passed to the Result Server

The DocVal server will pass the result on to the Result Server. The Result Server Url can be configured for each client_id. See the file INSTALL.html.

+---------------+    * Result (Passport Data & Check Results)     +------------------+
|               |    * Validation ID                              |                  |
| DocVal server |------------------------------------------------>|  Result Server   |
|               |                                                 |                  |
+---------------+                                                 +------------------+

This architecture was chosen to avoid that the DocVal server needs to store data about a passport.

Result JSON Example:

  "emrtd_passport": {
    "sod_info": ...,
    "mrz_info": ...,
    "face_photo": ...,
    "signature_photos": ...,
    "additional_personal_details": ...,
    "additional_document_details": ...,
    "passive_authentication": ...,
    "passive_authentication_details": ...,
    "chip_authentication_result": ...,
    "active_authentication_result": ...,
    "errors": ...
  "client_validation_id": "cf847daa-a548-4509-bdeb-4edd51aee448"

See the file emrtd_result.html for details about the Object "emrtd_passport". The "client_validation_id" is the validation_id provided by the client with the StartMessage.

Result is passed to the Client

If the URL Query parameter return_result is set to true (e.g. wss: // the DocVal server will also send the Result JSON to the client. See the file emrtd_result.html for an explanation of the emrtd_passport object.

Before the socket is closed

In some very special cases the iOS native URLSessionWebSocketTask on iOS 13 and 14 does not call the Close-Delegate-Function. Yet Wireshark recordings show that the ios client is indeed receiving and confirming the Close.

At this point, there are no clues indicating a bug in the server implementation, so we believe this is a URLSessionWebSocketTask related issue. Also with iOS 15 this issue seems to not exist anymore. The in-depth details about this behaviour are documented in the Server and IOS SDK Source Code.

To circumvent this downside and to ensure a reliable iOS Client, the close code and close reason are (unconventionally) sent as a json encoded text message.

Just before closing the WebSocket, the server will send the close_code and (conditional) the close_reason to the client as a json encoded text message. The Close-Codes and Close-Reasons to expect are defined in the two sections below.


  "close_code": 1000
  "close_code": 1011,
  "close_reason": "POST_TO_RESULT_SERVER_FAILED"

Client implementations that are reliably able to handle WebSocket-Session-Closes may in good conscience ignore this text message.

Socket is closed

When everything is done and no errors occurred, the DocVal server will close the WebSocket connection with Close Code 1000 and no explicit Close-Reason-Phrases.

Errors during the Process

If something goes wrong the server will close the Connection. The following Close-Reason-Phrases are possible:

    After opening the WebSocket session, the server did not receive the StartMessage in time.
    The Server did not receive an APDU Response in time.
    The WebSocket session was open longer than expected.
    The Server received an unexpected Text Message. The server only expects the StartMessage to be sent once per WebSocket session.
    The StartMessage is not correctly encoded. Ensure that the StartMessage contains the required fields and is correct JSON.
  • INVALID_ACCESS_KEY_VALUES The Access Key values are not valid. The CAN must be a 6 digit string. The Document Number must at least contain 8 characters. Date of Birth/Expiry must be encoded as "yyMMdd".
    WebSocket communication failed.
    An exception occurred while reading a file. See server log for details.
    An exception occurred during the read and verify process. See server log for details.
    A DocVal server side exception occurred. See server log for details.
    The DocVal server was unable to post the result to Result Server. Ensure that the Result Server is online and able to receive POST Request at the configured url.
    The Provided Client ID is not correct.
    Access Control was not successful. Ensure that the provided Access Key (CAN or MRZ Info) is correct.

The Close-Codes are from the WebSocket Protocol which is defined in RFC6455.

Because of this there can be multiple phrases for a single Close-Code.

A Close-Code reflects the raw status from the WebSocket, while the Close-Reason-Phrases communicate additional information from this server.

Get more information about
secure identity verification


    First Name *

    Last Name *

    Company *


    E-Mail *

    Phone *

    Message *


    I agree that my data from the contact form will be collected and processed to answer my request. You can find more information in our privacy policy.