Automated contact information synchronisation for verification methods

Introduction

Zivver offers effortless outbound email security. Using strong authentication for recipients is key to maintaining security and is required by regulations such as the Dutch NTA7516 and the European eIDAS framework. This means that sensitive content must be protected with recipient verification methods such as SMS or access codes. However, setting these up adds friction for users on top of their normal email flow.

Contact-Sync addresses this by enabling the automated synchronisation of contact information into Zivver via API. You can connect to this API from source systems such as CRMs or electronic patient record systems, ensuring that verification method information for contacts is always up to date. With this setup, strong authentication is available to users with minimal effort for both them and administrators.

High-level solution

We enable real-time management of contact information from any source system through a REST API. When an API integration from the customer’s system to Zivver is set up, Zivver contact data is automatically managed.

The API endpoint allows contacts to be created, retrieved, updated, and deleted with the following information:

  • Third-party unique identifier
  • Email address
  • Full name
  • Phone number(s)
  • Access code
  • Access code hint

The communication is one-directional: from the third-party system to Zivver, not vice versa.

Building an integration

Contact Sync exposes two API endpoints secured with an API key:

  • PATCH https://app.zivver.com/api/organization/verification_suggestions/contact_sync
  • GET https://app.zivver.com/api/organization/verification_suggestions/contact_sync/{third_party_id}

An API key can be generated at https://app.zivver.com/organization/api-keys by a Zivver administrator. The generated key must be added as an Authorization header to every API call made to this endpoint:

  • Authorization: Bearer {insert API key here}

Adding, updating, and deleting contacts can all be done in a single call, although this is not required. The structure for each contact is as follows:

  • thirdPartyId: Unique identifier of the contact within your organization (string, max 255 chars).
  • fullName: Full name of the contact (optional, string, max 255 chars).
  • email: Email address of the contact (optional, must be a valid email address).
  • phoneNumber: Phone number of the contact (optional, must be a valid number capable of receiving text messages).
    Accepted formats are 00<country code><number>, +<country code><number>, or <number> (if the number starts with a zero, the zero will be replaced with the country code). For example, a Dutch number can be provided as 0031612345678, +31612345678, or 0612345678.
  • accessCode: Access code for the contact (optional, string, max 255 chars).
  • accessCodeHint: Hint for the access code (optional, string, max 255 chars).

Adding contacts

To add a new contact, you must provide at least the thirdPartyId, email, and one of the following: phoneNumber or accessCode. Valid examples are:

{
    "thirdPartyId": "123",
    "email": "johndoe@gmail.com",
    "accessCode": "123"
}
{
    "thirdPartyId": "johndoe.12345",
    "fullName": "John Doe",
    "email": "johndoe@gmail.com",
    "phoneNumber": "+31612345678"
}
{
    "thirdPartyId": "abcdef",
    "email": "johndoe@gmail.com",
    "phoneNumber": "+31612345678",
    "accessCode": "123",
    "accessCodeHint": "The first three digits"
}

Retrieving contacts

The API allows you to retrieve the information for a single contact per call. To retrieve information for a specific contact, send a GET request to:

https://app.zivver.com/api/organization/verification_suggestions/contact_sync/{third_party_id}

Replace {third_party_id} with the ID of the contact you want to retrieve. For example:

GET https://app.zivver.com/api/organization/verification_suggestions/contact_sync/johndoe.12345

This request returns the following output:

{
    "items": [
        {
            "thirdPartyId": "johndoe.12345",
            "fullName": "John Doe",
            "email": "johndoe@gmail.com",
            "phoneNumber": "+31612345678"
        }
    ]
}

If there is no contact in your organization with this ID, the server responds with 404 Not Found.

Updating contacts

To update an existing contact, make sure to include all previously provided information, except for the value that needs to be changed. For example, if John Doe was added with the following information:

{
  "thirdPartyId": "johndoe.12345",
  "fullName": "John Doe",
  "email": "johndoe@gmail.com",
  "phoneNumber": "+31612345678"
}

If John Doe has changed his phone number, the updated data should look like this:

{
  "thirdPartyId": "johndoe.12345",
  "fullName": "John Doe",
  "email": "johndoe@gmail.com",
  "phoneNumber": "+31612345677"
}

Later, if John Doe has also changed his email address, the updated data should be:

{
  "thirdPartyId": "johndoe.12345",
  "fullName": "John Doe",
  "email": "johndoe@hotmail.com",
  "phoneNumber": "+31612345677"
}

Deleting data of a customer

In some cases, specific data of a customer may need to be deleted. For example, a customer might not want to receive a code via SMS because they don’t want their phone number to be stored by Zivver. In that case, only an access code should be provided instead.

For instance, if the following data was provided:

{
    "thirdPartyId": "johndoe.12345",
    "fullName": "John Doe",
    "email": "johndoe@gmail.com",
    "phoneNumber": "+31612345678"
}

To switch to an access code and remove the phone number from Zivver’s database, send the following data:

{
    "thirdPartyId": "johndoe.12345",
    "fullName": "John Doe",
    "email": "johndoe@gmail.com",
    "accessCode": "123"
}

Deleting a contact

To delete the contact data of a guest recipient, only the thirdPartyId needs to be provided. For example, if the following contact was added:

{
  "thirdPartyId": "johndoe.12345",
  "fullName": "John Doe",
  "email": "johndoe@gmail.com",
  "phoneNumber": "+31612345678"
}

It can be deleted by sending:

{
  "thirdPartyId": "johndoe.12345"
}

Sending data to Zivver

It is possible to send the contact details of each guest recipient individually to Zivver, or to group them. Sending a single contact to Zivver is done as follows:

{
    "items": [
        {
            "thirdPartyId": "134",
            "fullName": "John Doe",
            "email": "johnDoe@gmail.com",
            "accessCode": "123"
        }
    ]
}

Adding the contact data of a second guest recipient is done by adding a comma (,) after the first data point, followed by the second data point:

{
    "items": [
        {
            "thirdPartyId": "134",
            "fullName": "John Doe",
            "email": "john7@gmail.com",
            "accessCode": "123"
        },
        {
            "thirdPartyId": "135",
            "fullName": "John Doe",
            "email": "john8@gmail.com",
            "accessCode": "123"
        }
    ]
}

Additional contacts can be added in the same way: add a comma (,) after the previous contact, followed by the new contact.

Info
It is possible to send up to 1000 contacts in a single API call. If you need to send more than 1000 contacts, please split them into multiple calls.

Determining whether the data was received correctly

When Zivver receives contact data, it first validates the data and then either processes all of it or none of it. This means that if a batch of, for example, 5 data points is sent to Zivver and one is incorrect, none of the data points will be processed. In the API response, Zivver will indicate which data was incorrect and for which contact.

Note

Please take the following into account:

  • Zivver makes decisions based on the thirdPartyId of the contact. If the thirdPartyId already exists and new data with the same thirdPartyId is provided, the old data will be overwritten.
  • If the phone number cannot receive text messages, it will be considered invalid, and the contact data will not be stored or updated.
  • If neither accessCode nor phone number is defined, the data is invalid because no verification method is provided; in that case, the contact data will not be stored or updated.

When the data is valid, Zivver will return the number of newly added/updated contacts and the number of deleted contacts.

Each individual contact can also be verified using the GET endpoint.

Responses from Zivver’s API

Error responses

Duplicate thirdPartyId

{
    "items": [
        {
        "thirdPartyId": "134",
        "fullName": "John Doe",
        "email": "john7@gmail.com",
        "accessCode": "123"
        },
        {
        "thirdPartyId": "134",
        "fullName": "John Doe",
        "email": "john8@gmail.com",
        "accessCode": "123"
        }
    ]
}

This will result in a 400 error.

{
    "status": "duplicate third party ids were found",
    "data": [
        {
            "data": "134"
        }
   ]
}

No email address

{
    "items": [
        {
            "thirdPartyId": "134",
            "fullName": "John Doe",
            "accessCode": "123"
        }
    ]
}

This will result in a 400 error:

{
    "status": "Invalid data found",
    "data": [
        {
            "data": "Error for thirdPartyUserId 134: Email is invalid"
        }
    ]
}

No phone or access code provided

{
    "items": [
        {
            "thirdPartyId": "134",
            "fullName": "John Doe",
            "email": "John7@gmail.com"
        }
    ]
}

This will result in the following error response:

{
    "status": "Invalid data found",
    "data": [
        {
            "data": "Error for thirdPartyUserId 134: No phone or access code was specified"
        }
    ]
}

Success response

{
    "items": [
        {
            "thirdPartyId": "134",
            "fullName": "John Doe",
            "email": "john.doe@gmail.com",
            "accessCode": "123"
        },
        {
            "thirdPartyId": "135",
            "fullName": "Anne Smith",
            "email": "anne.smith@gmail.com",
            "accessCode": "123"
        },
        {
            "thirdPartyId": "136",
            "fullName": "Tom Jones",
            "email": "tom.jones@gmail.com",
            "accessCode": "123"
        }
    ]
}

A 200 response will be returned:

{
    "status": "Verification methods updated successfully",
    "data": {
        "recipientsAdded": 3,
        "recipientsDeleted": 0
    }
}