The Mako Provisioning API (henceforth "Mako API") provides the ability for partners to securely automate the creation of new Makos, Companies and Users. This documentation describes the Mako API and how to use it within your systems for greater integration with the Mako CMS.
For more detailed information on Mako API endpoints refer to Mako API Specification, which contains a list of endpoints, data models, sample requests and responses.
Client implementations in Python and Java are also available as a reference.
Prerequisites
Before using Mako API, you should have obtained API URL and credentials (client id and client secret) from Mako Networks. From now on, the URLs will be given in relative form to the base URL you received. You should be familiar with REST/JSON style API concepts.
Authentication
Mako API authentication follows the standard OAuth 2.0 Bearer Token flow. To obtain an authentication token, perform a POST to '/mako-api/auth/v1/auth' setting `client_id
and client_secret
as form params:
Content-Type: application/x-www-form-urlencoded; charset=utf-8
{
"access_token" : "YUMCABQAqX2cqBjSiFht",
"token_type" : "Bearer",
"expires_in" : 14400
}
If you provide invalid credentials, you will get the following error response:
{
"error" : "invalid_client"
}
Next, when making a request to a protected resource (i.e. everything except /auth
endpoint), include the bearer token in Authorization
header:
Authorization: Bearer YUMCABQAqX2cqBjSiFht
Make sure you re-authenticate and obtain a new token before the old one expires.
If there is any problem with the authentication token (missing, invalid, expired, etc.), you will get the following error:
{
"error" : "invalid_token"
}
If your IP/Subnet is not authorized to access Mako API, you will get the following error:
{
"status" : "FAILED",
"error" : {
"errorCode" : "unauthorizedSource",
"message" : "Unauthorized source"
}
}
Response envelope
Most Mako API responses are wrapped in a response envelope.[1] For example, when retrieving single mako information, the response will be the following:
{
"status" : "OK",
"body" : {
"id" : "708680cf-07c5-4618-94be-3b12ddb92d84",
"companyId" : "aa326232-c5f2-479e-8768-15430929497a",
"name" : "LON 6500 M/LTE",
"companyName" : "Some Company",
"identification" : "11:11:11:22:33:44"
}
}
If the request was successful, the body
field will contain the actual data of interest, such as Mako data, etc. In case of an error, you will receive a response similar to a one below:
POST /mako-api/config/v1/addMako
{
"status" : "FAILED",
"error" : {
"errorCode" : "noDataFound",
"message" : "Mako model not found"
}
}
Note that an erroneous response has an error
field instead of body
, where error code and message can be found. In case of e.g. validation errors, there might be more information returned in errorDetails
field:
{
"status" : "FAILED",
"error" : {
"errorCode" : "invalidData",
"message" : "Invalid data supplied",
"errorDetails" : {
"violations" : [ {
"path" : "mako.phoneNumber",
"message" : "must not be null"
}, {
"path" : "mako.address.address1",
"message" : "must not be null"
}, {
"path" : "mako.name",
"message" : "must not be null"
} ]
}
}
}
To recap, in order to confirm that the request was successful, verify both HTTP status code to be 200, and the status
field to be OK
.
Rate limiting
A per-user rate limit of 100 requests/sec is applied to all authenticated endpoints. The requests are counted per (user, endpoint), i.e. one user can perform max 100 requests/s to e.g. GET /mako-api/v1/config/getMako
endpoint. If you exceed the rate limit, you will get the following response:
{
"status" : "FAILED",
"error" : {
"errorCode" : "rateLimitExceeded",
"message" : "Rate limit exceeded"
}
}
Quotas
In addition to rate limiting, your requests are subject to daily quotas. Currently, quotas are applied to endpoints that create entities, e.g. POST /mako-api/config/v1/addMako
etc., and you are limited to 10,0000 such requests per user per day. Should you exceed the quota limit, you will receive the following response:
{
"status" : "FAILED",
"error" : {
"errorCode" : "quotaLimitExceeded",
"message" : "Quota limit exceeded"
}
}
Quota counters are reset every day at midnight (UTC).
Error handling
This section contains typical errors you can encounter when working with Mako API - some of them were already mentioned in the previous sections.
When checking if the request was successful, make sure HTTP status is 200 OK
and wrapped response status
field is OK
(unless it’s /auth
endpoint). Many errors (e.g. validation errors, invalid data, etc.) are returned with 200 OK
HTTP status code, so you have to account for that.
Some more high-level errors (e.g. method not allowed) do not return JSON, so your code should handle this. Below is the list of errors:
Error type | Status | Response | Comment |
---|---|---|---|
Invalid credentials |
401 |
|
Invalid credentials. Only returned by |
Invalid token |
401 |
|
Invalid, missing, or expired authentication token |
Unauthorized source |
401 |
|
Your IP/Subnet is not authorized to access Mako API |
Not found |
404 |
|
Endpoint not found, check if you haven’t mistyped the URL |
Method not allowed |
405 |
|
Wrong HTTP method used, e.g. PUT instead of POST etc. |
Unsupported media type |
415 |
|
Usually wrong |
Invalid parameter |
200 |
|
Invalid parameter value (applies to path params, etc.) |
Malformed JSON input |
200 |
|
Unparseable JSON sent. |
Invalid data |
200 |
|
This is a general error type for invalid request data. |
Invalid data - multiple violations |
200 |
|
Invalid request data - response contains multiple violations |
Internal server error |
500 |
|
Internal server error occurred. Contact Mako Networks. |
Rate limit exceeded |
429 |
|
You are performing requests too fast. |
Quota limit exceeded |
429 |
|
You have run out of quota for the given endpoint. You need to wait until the next day (UTC) to perform more requests to this endpoint. |
Quota limit exceeded |
429 |
|
You have run out of quota for the given endpoint. You need to wait until the next day (UTC) to perform more requests to this endpoint. |
General Error |
200 |
|
An umbrella error for various client-side error conditions. Please see the message to find out the reason for error. |
No data found |
200 |
|
Returned when trying to retrieve non-existent data, e.g. when wrong Mako ID was provided etc. |
Invalid state |
200 |
|
Returned when trying to perform an operation on an entity that’s in invalid state for the operation, e.g. deleting an already deleted Mako, etc. |
Duplicate entity |
200 |
|
Returned when some entity is already in use (e.g. trying to use Mako identification that was already used for some other Mako). |
Example workflow
Here’s an example workflow that demonstrates how to add a new company, and how to add a person, and a Mako for the newly created company. (authentication and HTTP status codes omitted for brevity)
First, let’s create a new company. You need to know the UUID of the parent company under which the new company will be created. (you may retrieve the list of companies using /listCompanies
endpoint)
{
"parentCompanyId" : "5f10c94d-af26-479f-a705-aa2a85d778ea",
"companyType" : "RESELLER",
"name" : "Acme",
"address" : {
"address1" : "3205 Sycamore Fork Road",
"suburb" : "Suburb",
"city" : "Fort Lauderdale",
"state" : "Florida",
"postOrZipCode" : "33308",
"country" : "US"
},
"phoneNumber" : "9542177110",
"supportEmail" : "test3@makonetworks.com",
"salesEmail" : "test2@makonetworks.com",
"generalEmail" : "test1@makonetworks.com"
}
{
"status" : "OK",
"body" : {
"id" : "e18ceab1-9071-41cc-a6dd-1e5bc2d5d962",
"name" : "Acme"
}
}
The response contains the unique id of the newly created company. Use this id to refer to the company in your future requests.
Now, we’re going to add a new person to the newly created company:
{
"companyId" : "f8a3ae1a-967a-4032-a053-e012cfe34537",
"userType" : "Full Reseller",
"templateScope" : "COMPANY_NO_INHERIT",
"firstName" : "Jane",
"lastName" : "Smith",
"username" : "acmereseller12",
"email" : "acmeresseler1@makonetworks.com",
"allowLogin" : true,
"address" : {
"address1" : "1355",
"address2" : "N McLean Blvd",
"city" : "Elgin",
"state" : "Illinois",
"postOrZipCode" : "60123",
"country" : "US",
"timezone" : "America/Chicago"
},
"phoneNumber" : "123423423"
}
{
"status" : "OK",
"body" : {
"id" : "f2034c04-be11-43b0-b39c-2535cd273661",
"firstName" : "Jane",
"lastName" : "Smith",
"username" : "acmereseller12",
"email" : "acmeresseler1@makonetworks.com"
}
}
Again, note the returned id
for the created person.
Finally, let’s add a Mako to the newly created company:
{
"companyId" : "f8a3ae1a-967a-4032-a053-e012cfe34537",
"name" : "Test Mako",
"address" : {
"address1" : "1355",
"address2" : "N McLean Blvd",
"suburb" : "Suburb",
"city" : "Elgin",
"state" : "Illinois",
"postOrZipCode" : "60123",
"country" : "US",
"timezone" : "America/Chicago",
"latitude" : 42.06,
"longitude" : -88.31
},
"phoneNumber" : "+18008514690",
"faxNumber" : "+18008514691",
"makoModel" : "Mako 6500-M"
}
{
"status" : "OK",
"body" : {
"id" : "7db65f69-ed6e-4b23-bf3f-2063b41ccdd1",
"companyId" : "f8a3ae1a-967a-4032-a053-e012cfe34537",
"name" : "Test Mako",
"companyName" : "Acme3",
"identification" : "MAKO-ID-HERE-5721-1587738483248"
}
}
When creating a Mako, a Mako model (hardware name), you can provide identification (Mac address), or you can create a mako using template (another Mako). Refer to API specification for details.