An API is basically just a website.

A website which only contains data (usually in the form of JSON), no html, CSS or java-script.

To call MOZ‘s API we have to make up a URL string which will be posted to the MOZ server. The server reads this Url (request) and decided which information you want. It send this information back either to the browser or to the programme which has been written to create the API call.

The process looks like this:

To call the MOZ API first we will need to work out what the request Url should look like.

To illustrate how to do this I will use the example of requesting the domain authority for the website comparethemarket.com. (Full disclosure .. I work for Compare the Market which is why I have chosen their website).

A completed url looks like this (login details have been altered):

https://lsapi.seomoz.com/linkscape/url-metrics/comparethemarket.com?Cols=68719476736&Limit=10&AccessID=member-mozscape-45676fedfgg11918&Expires=1519988622&Signature=dg%2bWtcTbVBg%2fQmtAIwcloy2S7aY%3d

This has been put together by the following steps:

  1. The HTTP or HTTPS request to the host name and resource.

http://lsapi.seomoz.com/linkscape/

2. The API command to call. Domain authority comes under url-metrics:

http://lsapi.seomoz.com/linkscape/url-metrics/

3. The target URL to analyze(in this case comparethemarket.com) .

http://lsapi.seomoz.com/linkscape/url-metrics/comparethemarket.com

4. The parameters to call. The ? indicates where the parameters begin. The & separates each parameter. The ‘Cols=’ then the number is the reference to which parameter you are querying (in this example domain authority which has been given the code 68719476736). The ‘Cols=’ is always before the number no matter which parameters/ information you want to find out.

https://lsapi.seomoz.com/linkscape/url-metrics/comparethemarket.com?Cols=68719476736&Limit=10&

The limit relates to the amount of decimal places you get back in the response for the domain authority.

5. Paste this url into your browser. A pop up is generated which asks for your authetication information.

Fill this in with your; Access ID and Secret Key.

You can generate your access ID and secret key here:

https://moz.com/products/api/keys

Free access allows for one request every ten seconds, up to 25,000 rows per month

When you fill this in your browser generates an ‘encrypted authentication’ string, a signature which is added to the end of the rest of the url.

The completed url looks like (I have altered secret key and signature information):

https://lsapi.seomoz.com/linkscape/url-metrics/comparethemarket.com?Cols=68719476736&Limit=10&AccessID=member-mozscape-454568fedfgg11918&Expires=1519088614&Signature=dg%2bWtcTbVBg%2gQcvAIwcloy2S7aP%3k

6. To call this url with a programme (written in C# or any other language). Then this end authentication signature needs to be encoded by your programme.

This signed authentication has 3 query string parameters to every call:

  1. AccessID
  2. Expires (UNIX timestamp in seconds) — how long the request is valid for .. should only be a few mins ahead of current time.
  3. Signature — an HMAC-SHA1 hash of your Access ID, the Expires parameter, and your Secret Key. The secure hash must be base64 encoded then URL-encoded before Mozscape accepts the signature as valid.

The final authentication string, which will be added to the end of the API call url should look like this (again information has been altered):

AccessID=member-cf180f1267&Expires=1267838899&Signature=LxvNXYcPqc%12BkapNKzHzYz2BI4SXfC%9H

What is the Encrypted signature?

Part 3, the encrypted signature relates to the “&Signature=” part at the end of the url call. The letters and numbers which come after this label are created by the following process:

  1. Create a HMAC hash from the 3 described paramaters (Access ID, Expires parameter, and Secret Key).

Access ID ==> HMAC-SHA1 String

The HMAC is a hash based method which takes some information, say a word, and character by character changes this inot hexidecimal numbers.

The SHA1 is the specific algorithm which is used to create the HMAC hash.

An example of a HMAC-SHA1 hash is;

a298f932c163f3abf36c324f1e252e81eec577ea

This is basically a string of hexidecimal characters.

(Generated using; https://www.freeformatter.com/hmac-generator.html).

2. Then we convert this Hexidecimal string to a base64 one.

Hexadecimal string ==> base64 string

A Hex is a base16 string. Base64 is shorter but has a much larger number of letters and characters which represent it.

An example of a base64 string is:

0kDaABnU4R+J6OiCjezSk5Io8vw=

(Generated using; http://tomeko.net/online_tools/hex_to_base64.php?lang=en).

3. Convert this base64 string to a url encoded string.

Base64 string ==> URL encrypted string

A base64 string can include characters which are not supported in a url. Since the encoded string generated needs to be posted in the url the last step is to url encrypt it.

An example of a url encoded string is:

0kDaABnU4R%2BJ6OiCjezSk5Io8vw%3D

Characters such as = cannot go in a url so this step has encoded these unsupported characters.

(Generated using; https://ostermiller.org/calc/encode.html).

An application written in C# which can request information from Moz’s API

The code would follow the same steps and order as above. The below example is only for the encryption aspect of the code as I have assumed putting together the rest of the Url request in code is fairly straight forward.

An Authentication class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace AuthenticatorPractice
{
public class AuthenticationHelper
{
private String accessID;
private String secretKey;
private int expiresInterval = 300;
private DateTime currentDate = DateTime.Now;
public AuthenticationHelper(String accessID)
{
this.accessID = accessID;
this.secretKey = this.GetSecretKey();
} public string GetSecretKey()
{
var mySecretKey = System.IO.File.ReadAllText(@"C:\dev\XXXXXXXXX\config.txt");
return mySecretKey;
} public int GetUNIXTimestamp()
{
var unixTime = currentDate.ToUniversalTime() -
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return (int)unixTime.TotalSeconds;
}
public int CreateAllowedAccessTime()
{
int allowedAccessTime = this.GetUNIXTimestamp() + expiresInterval;
return allowedAccessTime;
}
public string HmacSHA1AndBase64Encription(int allowedAccessTime)
{
var value = accessID + allowedAccessTime;
var key = secretKey;
//Setup secrete key as Bytes array
Byte[] secretBytes = UTF8Encoding.UTF8.GetBytes(key);
//Create new HMACSHA1 algorithm with this secretekey
var hmac = new HMACSHA1(secretBytes);
//create bytes array with the value information
Byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(value);
// 1.Call computeHash on the hmac string which contains the seceret key.
// This creates the hmac hash with the value information
// 2. This is converted to a Base64 String then returned.
return Convert.ToBase64String(hmac.ComputeHash(dataBytes));
}
public string UrlEncription(string base64String)
{
//httpUtility is microsoft class to help send things over web...
//The .UrlEncode is a built in method in HttpUtility class.
return System.Web.HttpUtility.UrlEncode(base64String);
}
public string CreateEncriptedSignature(int allowedAccessTime)
{
var hmacSHA1AndBase64Encription = this.HmacSHA1AndBase64Encription(allowedAccessTime);
var urlEncriptedString = this.UrlEncription(hmacSHA1AndBase64Encription);
return urlEncriptedString;
}
public String GetAuthenticationStr(string encryptedSignature, int allowedAccessTime)
{
// Need to remove whitespace in accessID with .Replace
String stringToSign = "AccessID=member-" + accessID.Replace(" ", "") + "&Expires=" + allowedAccessTime + "&Signature=" + encryptedSignature;
return stringToSign;
}
}
}

This class first creates the encrypted signature string, then appends this to a string with the AccessID and Expires details on.

To call and use this class the Programme.cs class would look like:

using System;namespace AuthenticatorPractice
{
class Program
{
static void Main(string[] args)
{

AuthenticationHelper aOuth = new AuthenticationHelper("mozscape - 45676fedfgg11918");
var accessTime1 = aOuth.CreateAllowedAccessTime();

var encryptedSignature = aOuth.CreateEncriptedSignature(accessTime1);
var authenticationStr = aOuth.GetAuthenticationStr(encryptedSignature, accessTime1);
Console.WriteLine(authenticationStr);
// var hmacHashString = aOuth.HmacSHA1HashString(accessTime1);
//Console.WriteLine(hmacHashString);
//var base64String = aOuth.Base64Encrption("dasbdsdnng%798700887777");
//Console.WriteLine(base64String);

//var urlEncryptStr = aOuth.UrlEncription(hmacHashString);
//Console.WriteLine(urlEncryptStr);

Console.ReadKey();

}
}
}

The repo for this programme can be found on my github: https://github.com/abitravers1989/autheticationSpike

Why has this encryption been done by Moz?

This has been done because Moz‘s database will most likely hold an encryption of your access ID and Secrete Key. They will have done the same steps (potentially bar the url encryption) once they generated your account information. This means they aren’t holding in their database (which can be seen by the engineers working for them or potentially someone who hacked in to get access) your information but instead they are holding an encoded version of it. This means someone would not be able to know your information if they got hold of the database which contains it.

This is an example of a one-way encryption.

In this article I have expanded on the documentation MOZ has put together on how to compose the request Url string to get information from its API. I have used the example of requesting domain authority for comparethemarket.com. If you want to see how to request any other information check out their documentation here.

I have demonstrated how to create the Url signature encryption with a C# application but if you want to use another language you can find examples of how to do so here.

--

--