Introduction

© 2006 - 2025 LEKAB Communication Systems AB. Version 5.1.201, 2025-04-28.

The messaging platform includes many features for keeping the address book up to date and in sync with external systems or directories. It is possible to import users and groups from Microsoft Azure Entra ID using the Graph API or import lists of contacts from .CSV or Excel files regularly from a shared folder via SFTP.

This API provides complete control of how the address book is kept up to date from an external system by providing a Restful API with full access to the contacts. The Web Service accepts HTTP GET, HTTP POST, HTTP PUT or HTTP DELETE requests when working with contacts and address books in the messaging platform. Both the GET and the POST versions return responses in the HTTP response body as a json document. Deleting contacts use the DELETE verb and updating expects PUT.

Some endpoints supports the same function with GET and POST, but in the GET case, parameters are given in the calling URL (after a ? sign, separated by & signs) , while in the POST case the parameters are given in a json document in the HTTP POST request body. UTF-8 encoding is assumed in all HTTP bodies.

The format of the input and output json documents and the input url parameters are described in this manual.

Metadata and contact properties

The endpoint /listtags can be used to present metadata used in the address book to users of the custom application you are building. These tags can later be used when sending messages by calling the REST SMS API. For example, if users see that there is a tag type called Group and values A, B and C, they can choose to send messages to all contacts that belong to group A. If another tag type is called City, the user can select one of multiple values and send messages to the matching contacts. It is possible to combine multiple tags to offer powerful and flexible addressing.

Address book name and ID

The endpoint /listaddressbooks will show which address books the API user has access to. The unique id of the address book is later used in other API calls to make sure that the correct address book is being modified. The name of an address book might be changed at any time by a user in the web portal. It is important to use the ID which is static and remains the same over time.

Not all address books visible to a user have proper names, and may instead be identified only as a certain user’s or organizational unit’s or company’s address book. The endpoint for listing addressbooks is intended to allow presentation of the available addressbooks to a human user for selecting the corresponding numeric id of the addressbook. The numeric id is then used with the other endpoints to specify which addressbook to operate on. The endpoint for listing tags gives a comprehensive list of all tag types and tag values in the address book, with counts for the number of occurrences.

Different authentication methods available for GET requests

The POST requests all use authentication by giving username and password in the corresponding fields in the JSON document which is sent in the (automatically HTTPS = SSL/TLS encoded) HTTP request body.

For GET requests we offer three different ways of supplying these credentials:

  1. Username and password can be sent in the U and P url parameters

  2. Username and password can be given in the HTTP headers, X-Lekab-Userid and X-Lekab-Password, respectively. The values have to be the Base64 encoding of (a UTF-8 byte array representation of) the username or password to allow non-US-ASCII characters. Here testuser will be encoded as dGVzdHVzZXI= and testpass as dGVzdHBhc3M=

  3. Username and password can be given as Basic authentication, i.e, the header Authorization should have the value Basic token, where the token is the Base64 encoding of (a UTF-8 byte array representation of) username:password. Here testuser:testpass will be encoded as dGVzdHVzZXI6dGVzdHBhc3M= and the Authorization header will have the value Basic dGVzdHVzZXI6dGVzdHBhc3M=

1. Modifying contacts in the address book

It is possible to List, Add, Delete and Update contacts in the address book.

When the external application is the master data source, it usually keeps a unique ID for each contact. This ID is used when saving a contact in the address book for the first time and later, to find, update or delete it.

A complete contact object with all properties should be provided by the calling application when using endpoints /addcontact and /updatecontact. It is not possible to update only specific parts of a contact, for example one of the addresses or one tag value. Applications should retrieve the whole contact, change whatever is needed and send it back to update. The complete contact object is returned in the JSON body when using /getcontact and /findcontactbyaddress. This makes it easy to modify the existing object before sending it back.

The process is simple:

  • Get a contact using the unique id (or by iterating through a search result).

  • Compare the content against your master data and change whatever is needed in the JSON structure.

  • Call /updatecontact and pass the modified JSON in the body. The same external id is used to find and update the existing contact.

2. Use cases for the address book API

One scenario could be that the security policy prevents granting read access to users and groups in Azure which is required by the Graph API. That means the polling for changes in Entra ID initiated from the messaging platform cannot be used. Instead, the address book API can be used to push changes initiated from the other directory. The customer builds their own integration and updates the address book in the messaging platform without sharing any access tokens or privileges to their Azure tenant.

The call to Address Book API can be added in a custom authentication flow where users request access to the Azure Groups used to subscribe to messages from the messaging platform. The Office 365 Groups connector for Power Platform and Azure Logic Apps has the OnGroupMembershipChange event that could be used to trigger events that update the address book.

Any SQL database or directory source can be integrated using the API in a similar way.

2.1. Opt-in to a group in Azure

  • A user request to join "Group A" in Azure and a flow is triggered.

  • A manager grants access for the user. The unique Azure user object id and group name are known (if only group id is known, lookup the group name so it can be used as tag value later).

  • The Address Book API is called:

  • Check if a contact already exist with the Azure user object id using /getcontact.

  • If the object id exists in the address book:

    • Update the tag type "Groups" and add the value "Group A".

    • Optionally, update the name and the mobile number in the SMS address, as well as the EMAIL address type.

    • Optionally, update other tag types such as City, Country, Street, etc. This could be useful when filtering and addressing.

    • Save the contact with a call to /updatecontact. It will overwrite the existing becaues it has the same contactid.

  • Else, if the object id does not exist in the address book:

    • Create a new contact with a contact id equal to the Azure user object id.

    • Add the name and the mobile phone as SMS address (also add the EMAIL address type if needed).

    • Add "Group A" as the value to the "Groups" tag type.

    • Optionally, add other tag types such as City, Country, Street, etc. This could be useful when filtering and addressing.

    • Save the contact with a call to /addcontact.

2.2. Opt-out from a group in Azure

  • Someone is removed from "Group A" and a flow is triggered. The unique Azure user object id and group name are known (if only group id is known, lookup the group name so it can be used as tag value later).

  • The Address Book API is called:

  • Check if a contact already exist with this object id using /getcontact.

  • If the contact with the id exists it is returned as a JSON object in the response:

    • Locate and update the tag type "Groups" and remove the value "Group A".

    • If other values remain in the "Groups" tag, keep them.

      • Save the changes to the existing contact using /updatecontact. It will overwrite the existing becaues it has the same contactid.

    • if "Group A" was the only value in "Groups":

      • Delete the whole contact using /deletecontact (unless the address book is used also for other use cases).

3. The /listaddressbooks endpoint

Not all address books, to which a user has reading rights, have proper names. They may instead be identified only as a certain user’s or organizational unit’s or company’s address book. This endpoint is intended to allow the presentation of available address books to a human user, who can thereby find the numeric id of the requisite address book. The numeric id is then used with the other endpoints to specify which address book to operate on. If no numeric id is given in the other endpoints, the default address book of the user calling the web service is assumed.

3.1. GET request example e.g. from web browser

GET https://secure.lekab.com/addressbook/api/listaddressbooks?U=doggykennel&P=testpass

3.2. POST request example, probably from an application

https://secure.lekab.com/addressbook/api/listaddressbooks

With the contents of the HTTP body:

{"username":"doggykennel","password":"testpass"}

3.2.1. Explanation of parameters

POST json key GET query param json value (strings quoted) query param value (strings without quotes)

username

U

string

string

username of the API account in the service

password

P

string

string

password of the API account in the service

3.2.2. HTTP response

A successful request will return 200 OK and a json document of the following format. If the user does not present proper login credentials or cannot read any address books, a 401 Unauthorized will be returned, with no json document.

{ "addressbooks" : [
     { "id" : 576978287400472577,
       "name" : "Kennel Company - Shared address book" },
     { "id" : 646802963557457921,
       "name" : "Doggy Kennel - Private address book" },
     { "id" : 646802966493470722,
       "name" : "Kennel Club Members" }]
}

while the alphanumeric recipient number was rejected.

3.2.3. Explanation of response

POST json key json value (strings quoted)

addressbooks

json list of json documents

list of address book items never empty because no accessible address books gives HTTP 401

id

json long integer

numeric id of this address book item

name

string

name of this address book item

3.2.4. Example Python 3 code for the /listaddressbooks endpoint

import json
import requests

bookreq =  {"username" : "doggykennel", "password": "testpass"}
bookreq_json = json.dumps(bookreq)
bookurl = 'https://secure.lekab.com/addressbook/api/listaddressbooks'
response = requests.post(bookurl, data=bookreq_json)
bookresp = response.json()
for a in bookresp["addressbooks"]:
    print(a["name"] + " has numeric id " + a["id"])

will output

Kennel Company - Shared address book has numeric id 576978287400472577
Doggy Kennel - Private address book has numeric id 646802963557457921
Kennel Club Members has numeric id 646802966493470722

4. The /listtags endpoint

A user, team or a company, can have an address book in the messaging platform, with contacts that each has a phonenumber that can receive SMS messages. These contacts can be marked with tags consisting of a tag type and a tag value, here often written separated by a colon character. For instance, a contact can be marked with the tag Base:STO if the person is based in Stockholm. Here Base is the tag type and STO is the tag value. The same contact can have many tags, for instance Group:Management or On call:Yes. Which tags types and tag values are used is up to the user/company, but they should preferably consist of letters and numbers, and can especially not contain the characters ;, | or :. The tags are used in several parts of the service to select addressees for messages using, so called, tag filters.

The /listtags endpoint is used to retrieve a comprehensive listing of all tags in a given address book, with counts for the number of occurrences.

4.1. GET request example e.g. from web browser

GET https://secure.lekab.com/addressbook/api/listtags?U=doggykennel&P=testpass&A=646802966493470722

4.2. POST request example, probably from an application

https://secure.lekab.com/addressbook/api/listtags

with the contents of the HTTP body:

{
  "username" : "doggykennel",
  "password" : "testpass",
  "addressbookid" : 646802966493470722
}

4.2.1. Explanation of parameters

POST json key GET query param json value (strings quoted) query param value (strings without quotes)

username

U

string

string

username of the API account in the service

password

P

string

string

password of the API account in the service

addressbookid

A

json long integer

number

id of the addressbook where tags are counted (optional, defaults to user’s default address book)

4.2.2. HTTP response

A successful request will return 200 OK and a json document of the following format.

{ "tags" : [ { "type" : "Breed",
               "typecount" : 250,
               "values" : [ { "value" : "German shepherd", "count" : 150 },
                            { "value" : "Labrador retriever", "count" : 57 },
                            { "value" : "Mutt", "count" : 43 } ] },
             { "type" : "Dog show newsletter",
               "typecount" : 104,
               "values" : [ { "value" : "Yes", "count" : 104 } ] } ],
 "addressbookid" : 646802966493470722,
 "addressbookname" : "Kennel Club Members" }

4.2.3. Explanation of response

POST json key json value (strings quoted)

addressbookid

json long integer

the id of the address book searched

addressbookname

string

name of the address book searched

tags

json list of json documents

one type item per tag type

type

string

tag type in this type item

typecount

integer

number of tags with this tag type in the addressbook

values

json list of json documents

one value item per tag value

value

string

tag value in this value item

count

integer

number of tags with this tag value and tag type in the addressbook

4.2.4. Example Python 3 code for the /listtags endpoint

import json
import requests

tagsreq =  {"username" : "doggykennel", "password" : "testpass", "addressbookid" : 646802966493470722}
tagsreq_json = json.dumps(tagsreq)
tagsurl = 'https://secure.lekab.com/addressbook/api/listtags'
response = requests.post(tagsurl, data=tagsreq_json)
tagsresp = response.json()
print("Listing tags in " + tagsresp["addressbookname"])
for a in tagsresp["tags"]:
    print(a["type"] + " occurs " + str(a["typecount"]) + " times, with " + str(len(a["values"])) + " different values")

will output

Listing tags in Kennel Club Members
Breed occurs 250 times, with 3 different values
Dog show newsletter occurs 104 times, with 1 different values

5. Finding existing contacts with filters

5.1. The /getcontact endpoint

Find a contact with a specific external id, for example Azure Object ID:

GET https://secure.lekab.com/addressbook/api/getcontact?contactid=f32ca8c1-63ed-4a1e-ad2c-e88157c7e991

5.2. The /findcontactbyaddress endpoint

Find contacts with a specific mobile number in the SMS address (usually only one but there could be duplicates):

GET https://secure.lekab.com/addressbook/api/findcontactbyaddress?addresstype=SMS&address=46701234567

Find all contacts that can receive SMS messages because they have that address type:

GET https://secure.lekab.com/addressbook/api/findcontactbyaddress?addresstype=SMS

Find all contacts that can receive VOICE calls with Text-to-speech conversion or using MP3 playback:

GET https://secure.lekab.com/addressbook/api/findcontactbyaddress?addresstype=VOICE

Find all contacts that can receive E-mails:

GET https://secure.lekab.com/addressbook/api/findcontactbyaddress?addresstype=EMAIL

Find all contacts that are configured with a custom iOS or Android app address for push notifications:

GET https://secure.lekab.com/addressbook/api/findcontactbyaddress?addresstype=APP

Find contacts with a specific address, regardless of type. For example, check if a phone number exist either as SMS or VOICE type

GET https://secure.lekab.com/addressbook/api/findcontactbyaddress?address=46701234567

6. List all contacts created or modified after a specific time

Sometimes it is useful to keep track of modifications since the last time a scheduled task was performed. Contacts in the address book have properties for created time and updated time. Note that a contact can be updated by a user in the web portal. This will change the updated timestamp. There is also a field with the information about who made the update.

The time format used in GET is YYYY-MM-DDTHH:MM:SS+0100 and must be URL-encoded. A time zone can be added, for example: YYYY-MM-DDTHH:MM:SS+0100

It is possible to specify the specific address book to search, by adding the id to the request. The /listaddressbooks endpoint is used to find the id.

Find all contacts created after a specific date/time. Search in all address books the api user has access to (no address book id appended to the uri path):

GET https://secure.lekab.com/addressbook/api/contacts/createdafter/2025-03-30T00%3A00%3A00%2B0100/

Find all contacts created after 2025-03-30 in a specific address book. The addressbook id 1086241428642066431 is added at the end:

GET https://secure.lekab.com/addressbook/api/contacts/createdafter/2025-03-30T00%3A00%3A00%2B0100/1086241428642066431

Find all contacts modified after 2025-03-30, in all address books the api user has access to:

GET https://secure.lekab.com/addressbook/api/contacts/modifiedafter/2025-03-30T00%3A00%3A00%2B0100/

Find all contacts modified after 2025-03-30 in a specific address book. The addressbook id 1086241428642066431 is added at the end:

GET https://secure.lekab.com/addressbook/api/contacts/modifiedafter/2025-03-30T00%3A00%3A00%2B0100/1086241428642066431

7. The /addcontact endpoint

Adding a contact uses the POST verb. The contact object is sent in the body as a JSON document. The contact has some general properties such as Name and Company. The unique contactid is important when you plan to search for and update the contact at later time. The Addresses and Tags are lists.

The address types can be SMS, EMAIL, VOICE or APP. When using SMS and VOICE, make sure that the phone number in the address field is a complete number including international prefix. Do not use a plus "+". Please refer to the E.164 standard for more information about phone number format.

To add a contact with a specific external Azure Object ID:

POST https://secure.lekab.com/addressbook/api/addcontact
{
  "addressbookid": "925406391282233345",
  "contactid": "f32ca8c1-63ed-4a1e-ad2c-e88157c7e991",
  "contactname": "Eva Nilsson",
  "companyname": "Test company",
  "addresses": [
    {
      "addresstype": "SMS",
      "address": "46701234567"
    },
    {
      "addresstype": "VOICE",
      "address": "46701234567"
    },
    {
      "addresstype": "EMAIL",
      "address": "eva.nilsson@test.company.xyz"
    }
  ],
  "tags": [
    {
      "tagtype": "Groups",
      "tag": "Group A"
    },
    {
      "tagtype": "City",
      "tag": "Stockholm"
    }
  ]
}

8. The /updatecontact endpoint

Updating a contact uses the PUT verb. The contact object is sent in the body as a JSON document. For information about the JSON body, please refer to /addcontact.

To update a contact with a specific external Azure Object ID:

PUT https://secure.lekab.com/addressbook/api/updatecontact
{
  "addressbookid": "925406391282233345",
  "contactid": "f32ca8c1-63ed-4a1e-ad2c-e88157c7e991",
  "contactname": "Eva Nilsson",
  "companyname": "Test company",
  "addresses": [
    {
      "addresstype": "SMS",
      "address": "46701234567"
    },
    {
      "addresstype": "VOICE",
      "address": "46701234567"
    },
    {
      "addresstype": "EMAIL",
      "address": "eva.nilsson@test.company.xyz"
    }
  ],
  "tags": [
    {
      "tagtype": "Groups",
      "tag": "Group A"
    },
    {
      "tagtype": "City",
      "tag": "Stockholm"
    }
  ]
}

9. The /deletecontact endpoint

Deleting a contact uses the DELETE verb. The contactid is sent in the body as a JSON document.

To delete a contact with a specific external Azure Object ID:

DELETE https://secure.lekab.com/addressbook/api/deletecontact
{
    "addressbookid": "925406391282233345",
    "contactid": "f32ca8c1-63ed-4a1e-ad2c-e88157c7e991"
}

Note: The address Book ID is optional but recommended. The default address book of the API user is used if the parameter is missing. To list all address books the api user has access to, please refer to the /listaddressbooks endpoint.

10. The /deleteallcontacts endpoint

Warning – use with caution. This request will empty the address book by deleting all contacts. In many scenarios, the application using the API is keeping track of changes and updates only specific contacts based on their id or date/time last modified. However, in some cases the application might just want to empty the address book and add all contacts at once. For this purpose, the delete all endpoint was added.

Note that tag filters in the address book remain after deleting all contacts. For example, if users in the web portal have prepared addressing filters for contacts matching tag type City=Stockholm and Department=Sales, these filters remain and will become useful again when the new contacts are added. Usually the deleteallcontacts call is followed by calls to /addcontact within a few seconds and will not interfer with users who are logged in and sending messages. However, if the process is adding thousands of conects and takes some time, it should be scheduled at night-time. Updating individual contacts instead of "delete all - add all" always cause less disturbance if users are expecteds to be active 24/7.

To delete all contacts in the address book with id 925406391282233345:

DELETE https://secure.lekab.com/addressbook/api/deleteallcontacts?addressbookid=925406391282233345

Note: The address Book ID is mandatory when deleting all contacts. To list all address books the api user has access to, please refer to the /listaddressbooks endpoint.