The Common CRM API exposes the members resource of the Link Mobility CRM software, in a RESTful API. Members can be pushed to Link CRM from other software, or it can be pulled from CRM into other software.
Base URL
...
https://crm-api.linkmobility.com/api/sdk/http://crm-api.linkmobility.com/swagger/ui/index#!/Sdk
Connect thru SDK (optional)
If you have a .Net application for your business, you can leverage the SDK experience using the nuget command below. SDK will handle the authentication part out of the box.
Code Block |
---|
Install-Package LinkMobility.CommonCrm.Sdk -Version 1.0.0 -Source https://www.myget.org/F/linknorway/api/v3/index.json |
Swagger docs
Swagger documentation page
Autentication
The API uses HMAC-SHA256 authentication. The request header hmac contains the partnerId, a message signature, the nonce and the timestamp, separated by :. The hmac signature is generated by hashing partnerId, http verb, uri, timestamp, nonce, and an MD5 of the content, if there is any, with SHA256.
Signature parts | How to generate |
---|
PartnerId | As provided |
HTTP Method | The HTTP Method of the request |
URI | The absolute uri of the request, lower cased, and then url encoded |
Timestamp | The number of seconds since epoch UTC |
Nonce | A UUID |
Content | If there is a payload on the request, MD5-hash it. |
All of the above parts are concatenated into one string. The UTF8 encoded bytes of the string are then hashed using HMAC-SHA256, using the provided secret key, to generate a signature of the request. This signature is then base-64 encoded.
The header is then built by concatenating the partnerId, the first 10 characters of the encoded signature, the nonce and the timestamp, separated by :.
Code Block |
---|
Authorization: hmac 11263:1ObfMLHlvK:2e4603e46dfd489294af13513db02c0a:1453801859 |
|
Sample C# code for generating the header:
| Code Block |
---|
static void Main(string[] args)
{
var secretkey = "<your base-64 encoded secret key here>";
var partnerId = <your partner id here>;
var url = "https://crm-api.linkmobility.com/api/sdk/members/<a valid group id here>/<a valid member id here>";
var method = "GET";
var timestamp = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
var nonce = Guid.NewGuid().ToString("N");
var data = partnerId + method + WebUtility.UrlEncode(url.ToLower()) + timestamp + nonce;
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(secretkey));
var signedData = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
var signaturePart = Convert.ToBase64String(signedData).Substring(0, 10);
var authHeader = string.Format("hmac {0}:{1}:{2}:{3}", partnerId, signaturePart, nonce, timestamp);
Console.WriteLine(signature);
Console.ReadLine();
} |
|
Sample node.js for generating hmac header
| Code Block |
---|
const crypto = require('crypto');
const uuid = require('node-uuid');
function generateHmacHeader(sharedSecret, partnerId, httpVerb, uri, requestPayload) {
var nonce = uuid.v4();
var timestamp = Math.floor(new Date().getTime() / 1000);
var md5Content = '';
if (requestPayload) {
md5Content = crypto.createHash('md5');
}
var signatureString = partnerId + httpVerb + encodeURIComponent(uri.toLowerCase()) + timestamp + nonce + md5Content;
var hmacSignature = crypto.createHmac('SHA256', new Buffer(sharedSecret, 'base64'))
.update(signatureString, 'utf8')
.digest('base64');
return 'hmac ' + [partnerId, hmacSignature.substring(0, 10), nonce, timestamp].join(':');
} |
|
Sample python code for generating hmac header (credit: www.skylabs.no)
| Code Block |
---|
import uuid
import base64
import hashlib
import hmac
import time
import urllib
class LinkNext:
api_root = 'https://crm-api.linkmobility.com/api/sdk'
partnerid = None
hmac_key = None
def __init__(self, partnerid, hmac_key):
self.partnerid = partnerid
self.hmac_key = hmac_key.decode('base64')
def _generateHMAC(self, uri, http_verb, request = None):
nonce = uuid.uuid4().hex
string_timestamp = str(int(time.time()))
requestmd5 = ""
url_encoded = urllib.quote_plus(uri.lower())
if(request):
request_json = json.dumps(request)
request_bytes = request_json.decode('utf-8')
requestmd5 = hashlib.md5(request_bytes).digest().encode('base64').strip()
signature_string = '{0}{1}{2}{3}{4}{5}'.format(str(self.partnerid), http_verb, url_encoded, string_timestamp, str(nonce), requestmd5)
hmac_signature = hmac.new(self.hmac_key, signature_string, hashlib.sha256)
base64_hmac_signature = hmac_signature.digest().encode('base64')
hmac_header = '\"{0}:{1}:{2}:{3}\"'.format(str(self.partnerid), base64_hmac_signature[:10], nonce, string_timestamp)
header = {'Authorization': 'hmac {0}'.format(hmac_header)}
return header |
|
Sample PHP code example for generating HMAC header
Code Block |
---|
<?php
$partner_id = '<your partner id>'; // from LINK Mobility
$secret_key = '<your secret key>'; // from LINK Mobility
$secret_key = base64_decode($secret_key);
# EXAMPLE generating HMAC for GET request to api/sdk/members/<groupId><memberId>
$request_method = strtoupper("GET");
$url = 'https://crm-api.linkmobility.com/api/sdk/members/771/08F8DCB2-21CA-4661-B6DD-3F553C5449FD';
$url = strtolower($url);
$request_content = '';
$auth_header = getAuthHeader($partner_id, $secret_key, $request_method, $url, $request_content);
echo $auth_header; // display the Authorization: header to be included in the request
function getAuthHeader($partner_id, $secret_key, $request_method, $url, $request_content) {
# generate Authorization Header
$requestUri = urlencode($url);
$requestTimeStamp = time(); // current UNIX timestamp
$nonce = uniqid(); // string
if ( !empty($request_content) ) {
$requestContentMd5Hash = md5($request_content, true); /* raw binary format with length of 16 */
} else {
$requestContentMd5Hash = $request_content;
}
$request_content = base64_encode($requestContentMd5Hash);
$signatureRawData = ($partner_id . $request_method . $requestUri . $requestTimeStamp . $nonce . $request_content );
$utf8_data = utf8_encode($signatureRawData);
$hmac_before_base64 = hash_hmac ( 'sha256', $utf8_data , $secret_key, true ); // not raw digital output
$hmac_base64_encoded = base64_encode ( $hmac_before_base64);
$hmac_substringed = mb_substr ( $hmac_base64_encoded, 0, 10, 'UTF-8' );
$auth_header = "Authorization: hmac $partner_id:$hmac_substringed:$nonce:$requestTimeStamp";
return $auth_header;
}
?> |
|
Formats
The response from GET requests will by default be formatted as XML. If you prefer to use JSON, you can append the following to the URI: ?$format=json.
...
Gets the member information by providing the groupId and the internal member id.
URI params
Name | Description |
---|
groupId | An existing Link CRM groupId (internal) |
memberId | An existing Link CRM memberId (internal) |
Sample response
Code Block |
---|
{
"memberId":"86435f0f-bd85-418c-9c74-fa985068c1b4",
"active":true,
"groupId":481,
"externalId":null,
"msisdn":"45066506",
"countryCode":"47",
"firstName":"Kjersti",
"lastName":"Berg",
"streetAddress":"Gaustadalléen 21",
"zipCode":"0349",
"city":"Oslo",
"location":{
"latitude":59.942219906222,
"longitude":10.715902555317
},
"birthDate":null,
"gender":1,
"email":null,
"regDateUtc":"2016-01-25T13:19:00Z",
"modifiedByUserDateUtc":null,
"daysSinceRegistration":1,
"minutesSinceRegistration":1235,
"hasBirthDay":false,
"modifiedByUser":false,
"customProperties":null
} |
|
GET /members?groupId={groupId}&externalId={externalId}
Query params
Name | Description |
---|
groupId | An existing Link CRM groupId (internal) |
externalId | An existing Link CRM member externalId |
Sample response
Code Block |
---|
{
"memberId":"86435f0f-bd85-418c-9c74-fa985068c1b4",
"active":true,
"groupId":481,
"externalId":"abc123",
"msisdn":"45066506",
"countryCode":"47",
"firstName":"Kjersti",
"lastName":"Berg",
"streetAddress":"Gaustadalléen 21",
"zipCode":"0349",
"city":"Oslo",
"location":{
"latitude":59.942219906222,
"longitude":10.715902555317
},
"birthDate":null,
"gender":1,
"email":null,
"regDateUtc":"2016-01-25T13:19:00Z",
"modifiedByUserDateUtc":null,
"daysSinceRegistration":1,
"minutesSinceRegistration":1235,
"hasBirthDay":false,
"modifiedByUser":false,
"customProperties":null
} |
|
GET /members?groupId={groupId}&countryCode={countryCode}&msisdn={msisdn}
Lookup a member resource by MSISDN.
Query params
Name | Description |
---|
groupId | An existing Link CRM groupId (internal) |
countryCode | Country code of the member phone number, i.e. 47. |
msisdn | Member phone number, i.e. 99999999 |
Sample response
Code Block |
---|
{
"memberId":"86435f0f-bd85-418c-9c74-fa985068c1b4",
"active":true,
"groupId":481,
"externalId":null,
"msisdn":"45066506",
"countryCode":"47",
"firstName":"Kjersti",
"lastName":"Berg",
"streetAddress":"Gaustadalléen 21",
"zipCode":"0349",
"city":"Oslo",
"location":{
"latitude":59.942219906222,
"longitude":10.715902555317
},
"birthDate":null,
"gender":1,
"email":null,
"regDateUtc":"2016-01-25T13:19:00Z",
"modifiedByUserDateUtc":null,
"daysSinceRegistration":1,
"minutesSinceRegistration":1235,
"hasBirthDay":false,
"modifiedByUser":false,
"customProperties":null
} |
|
POST /members
Creates a new member. The payload is an XML or JSON formatted representation of the new member resource.
Data | Description |
---|
Msisdn | The member phone number, not including country code. E.g. 99999999 |
CountryCode | The member phone number country code, E.g. 47 |
GroupId | Link CRM groupId. |
ExternalId | Optional. Can be used to link to an Id in an external system. |
FirstName | Optional. The member's first name. |
LastName | Optional. The member's last name. |
StreetAddress | Optional. The member's street address. |
ZipCode | Optional. The member's zip code. |
City | Optional. The member's city. |
Location | Optional. The member's geolocation, specified with latitude and longitude. E.g. Code Block |
---|
{
latitude: 51.5034070,
longitude: -0.1275920
} |
|
BirthDate | Optional. The member's birth date. |
Gender | The member's gender. 0 = unspecified, 1 = female, 2 = male. |
Email | Optional. The member's email. |
CustomProperties | Optional. In Link CRM there is an option to attach custom properties to member resources. These must be defined in Link CRM to be used in the API. |
Sample response
Code Block |
---|
HTTP/1.1 201 Created
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location
Content-Length: 0
Date: Tue, 26 Jan 2016 10:03:11 GMT
Location: https://crm-api.linkmobility.com/api/members/a7247840-95c5-479d-954a-de492e564650
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET |
|
PUT /members/{groupId}/{memberId}
Updates an existing member.
URL params
groupId | An existing Link CRM groupId (internal) |
memberId | An existing Link CRM memberId (internal) |
The updated member resource is included in the request body, as XML or JSON. Set the appropriate content-type in the request header.
The payload will replace the existing member resource identified by that memberId.
Sample response
Code Block |
---|
HTTP/1.1 204 No content
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location
Content-Length: 0
Date: Tue, 26 Jan 2016 11:22:02 GMT
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET |
|
Error codes
Code | Result |
---|
401 Hmac timestamp clock-drift too high | The timestamp used to generate the hmac token is too old. |
401 Invalid HMAC | The hmac token in the Authorization header has some invalid content. |
400 Member id <id> not found | The provided memberId does not exist |
400 Group id <id> not found | The provided groupId does not exist |