This article is a simple guide on how to use CLUe API to retrieve event logs from CLUe Server.
Below examples uses cURL and C# WPF .NET examples.
TABLE OF CONTENTS
Prerequisite
In order to use CLUe API, you must have the following information.
- Your store's PlaceID
- Login Information
- API Access Token - this is obtained from Logging in to CLUe.
Login
To use CLUe API, you must have an Access Token.
This access token can be obtained by logging in to CLUe with your login information.
1. API endpoint and Parameters
[POST] https://api.moon.supremainc.com/v1/accounts/login/phone
2. Request Body
Please request below information from your Suprema Agent.
Field | Type | Required | Description |
---|---|---|---|
countryCode | string | yes | country code |
phone | string | yes | login id |
password | string | yes | password |
accountType | string | yes | account type |
authDeviceType | string | yes | authentication device type |
curl --location 'https://api.moon.supremainc.com/v1/accounts/login/phone' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "countryCode" : "kr", "phone" : "0123456789", "password" : "Pa$sw0rd", "accountType" : "BUSINESS_OWNER", "authDeviceType" : "MOBILE_APP" } '
3. Response Body
Field | Type | Nullable | Description |
---|---|---|---|
code | Number | false | API response code |
status | Boolean | false | API response status |
message | String | false | API response message |
data.accountId | Number | false | account id |
data.accountType | String | false | USER / SUPREMA_MANUFACTURE / SERVICE_PROVIDER/ SERVICE_OPERATOR / BUSINESS_PROVIDER/ BUSINESS_OWNER |
data.accountStatus | String | false | INACTIVE ACTIVE AUTH_CODE_LOCKED AUTH_CODE_TOO_MANY_SEND PASSWORD_LOCKED PASSWORD_EXPIRED DELETE_RESERVE |
data.name | String | false | account name |
data.countryCode | String | false | account countryCode |
data.phone | String | false | account phone number |
data.accessToken | String | false | API accessToken |
data.refreshToken | String | false | API refreshToken |
HTTP/1.1 200 OK Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json Content-Length: 626 { "code" : 200, "status" : true, "message" : "OK", "data" : { "accountId" : 1, "accountType" : "BUSINESS_OWNER", "accountStatus" : "ACTIVE", "name" : "diaz", "countryCode" : "kr", "phone" : "01234567890", "accessToken" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0dGMiOiJhYyIsImR0YyI6Im1hIiwiZXhwIjoxNjcwODA3ODUzLCJyaWMiOjEsImlhdCI6MTY3MDgwNDI1M30.i-jEiLGExOQGotdy-VGEmDx45gV4LtVJ_waoH18sfog", "refreshToken" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0dGMiOiJyZSIsImR0YyI6Im1hIiwiZXhwIjoxNzAyMzQwMjUzLCJyaWMiOjEsImlhdCI6MTY3MDgwNDI1M30.2idXYbteVFfFDSnYecM3QpW5KBHERrEIx3kZX0L77hw" } }
The important point here is to get the Access Token from the response body and use this value as Authorization Header in other API calls.
4. Sample Code in C#
static async Task<string> LoginTask() { sAccessToken = null; string jsonRequestBody = "{"; jsonRequestBody += "\"countryCode\" : \"" + sCountryCode + "\","; jsonRequestBody += "\"phone\" : \"" + sPhone + "\","; jsonRequestBody += "\"password\" : \"" + sPassword + "\","; jsonRequestBody += "\"accountType\" : \"" + sAccountType + "\","; jsonRequestBody += "\"authDeviceType\" : \"" + sAuthDeviceType + "\"}"; using (HttpClient client = new HttpClient()) { string apiUrl = "https://api.moon.supremainc.com/v1/accounts/login/phone"; // Set the JSON content StringContent content = new StringContent(jsonRequestBody, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync(apiUrl, content); if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); sLoginResponse = responseBody; var loginResponse = LoginResponse.FromJson(responseBody); sAccessToken = loginResponse.Data.AccessToken; } else { string responseBody = await response.Content.ReadAsStringAsync(); var clueErrorResponse = ClueErrorResponse.FromJson(responseBody); string errorResponse = clueErrorResponse.Errors[0].Code + ":" + clueErrorResponse.Errors[0].Message; MessageBox.Show("失敗しました。\n" + errorResponse, "Error"); } } return sAccessToken; }
sAccessToken = the access token retrieved from the response body
Retrieve Logs
1. API endpoint and Parameters
[GET] https://api.moon.supremainc.com/v1/events/places/:placeId
Request Header:
Key | Type | Required | Description |
---|---|---|---|
Authorization | JWT Token | yes | Access Token retrieved from Login API |
Path Variables:
Key | Type | Required | Description |
---|---|---|---|
placeId | Number | yes | The assigned placeID of your store. Please request information from Suprema Agent. |
Query Parameter:
Key | Type | Required | Description |
---|---|---|---|
startTime | Unix Time (Millisec) | no | retrieve logs starting this date if not specified, all logs are displayed |
endTime | Unix Time (Millisec) | no | retrieve logs until this date if not specified, all logs are displayed |
filterEvents | string | no | display only events with the specified event type. if not specified, all logs are displayed |
page | Number | no | logs are displayed in multiples pages. if not specified, displayed in 1 page only. |
size | Number | no | number of logs to be retirieved from the startTime |
sort | string | no | sort the logs by ID in ascending ('asc') or descending ('desc') order Example: id%2Cdesc |
curl --location 'https://api.moon.supremainc.com/v1/events/places/178?startTime=1675124016000&endTime=1703981616000&filterEvents=DEV_FACE_AUTH_SUCCESS&page=0&size=256&sort=id%2Cdesc' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0dGMiOiJhYyIsImR0YyI6Im1hIiwiZXhwIjoxNjk0NzM1OTkxLCJyaWMiOjM1LCJpYXQiOjE2OTQ3MzIzOTF9.yH_Fc7j4CDHEMNVoDdstakVNqtYbkXTN5-JFM3tgaJY'
2. Request Body
None
3. Response Body
Field | Type | Nullable | Description |
---|---|---|---|
code | Number | false | API response code |
status | Boolean | false | API response status |
message | String | false | API response message |
total | Number | false | total number of retrieved logs. |
data.logId | Number | false | CLUe server side's log ID. |
data.eventAt | Unix Time | false | Date and time when the event occurred. |
data.placeId | Number | false | Place ID |
data.deviceId | Number | true | Device ID |
data.doorId | Number | true | Door ID |
data.doorName | String | true | Door Name |
data.authId | Number | true | Authentication ID |
data.userId | Number | true | User Key |
data.useName | String | true | User Name |
data.localLogId | Number | false | Device side's log ID |
data.eventType | Event Type | false | event type |
HTTP/1.1 200 OK Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json Content-Length: 634 { { "code": 200, "status": true, "message": "OK", "total": 507, "data": [ { "logId": 12907987, "eventAt": 1694066002529, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4607, "eventType": "DEV_DOOR_RELAY_OFF" }, { "logId": 12907979, "eventAt": 1694065999512, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4606, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12907978, "eventAt": 1694065999471, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4605, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12907965, "eventAt": 1694065996127, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4604, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907955, "eventAt": 1694065992829, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4603, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907951, "eventAt": 1694065989790, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4602, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907946, "eventAt": 1694065986920, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4601, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907942, "eventAt": 1694065983825, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4600, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907937, "eventAt": 1694065980832, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4599, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907933, "eventAt": 1694065977903, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4598, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907924, "eventAt": 1694065974147, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4597, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907915, "eventAt": 1694065969479, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4596, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907880, "eventAt": 1694065948852, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4595, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907853, "eventAt": 1694065943870, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4594, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907837, "eventAt": 1694065940445, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4593, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907831, "eventAt": 1694065937586, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4592, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12907819, "eventAt": 1694065926868, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4591, "eventType": "DEV_FACE_AUTH_FAIL" }, { "logId": 12905071, "eventAt": 1694063933649, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4590, "eventType": "DEV_DOOR_RELAY_OFF" }, { "logId": 12905069, "eventAt": 1694063930647, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4589, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12905066, "eventAt": 1694063930569, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4588, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12905065, "eventAt": 1694063930492, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4587, "eventType": "DEV_DOOR_RELAY_OFF" }, { "logId": 12905064, "eventAt": 1694063927477, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4586, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12905062, "eventAt": 1694063927452, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4585, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12905060, "eventAt": 1694063924568, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4584, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12905058, "eventAt": 1694063924490, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4583, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12905055, "eventAt": 1694063921597, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4582, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12905052, "eventAt": 1694063921556, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4581, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12904676, "eventAt": 1694063600474, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4580, "eventType": "DEV_DOOR_RELAY_OFF" }, { "logId": 12904672, "eventAt": 1694063597477, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4579, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12904671, "eventAt": 1694063597440, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4578, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12904667, "eventAt": 1694063594788, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4577, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12904664, "eventAt": 1694063594753, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8744, "doorName": "testDoor", "userId": "12345678", "userName": "EBISU", "localLogId": 4576, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12904657, "eventAt": 1694063590253, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4575, "eventType": "DEV_DOOR_RELAY_OFF" }, { "logId": 12904651, "eventAt": 1694063587211, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4574, "eventType": "DEV_DOOR_RELAY_ON" }, { "logId": 12904650, "eventAt": 1694063587143, "placeId": 178, "deviceId": 902, "doorId": 181, "authId": 8173, "doorName": "testDoor", "userId": "34567", "userName": "Jack", "localLogId": 4573, "eventType": "DEV_FACE_AUTH_SUCCESS" }, { "logId": 12904640, "eventAt": 1694063580664, "placeId": 178, "deviceId": 902, "doorId": 181, "localLogId": 4572, "eventType": "DEV_FACE_AUTH_FAIL" } ] } }
4. Sample Code in C#
static async Task<string> GetLogEvents( string placeID, int numOfLogs ) { using (HttpClient client = new HttpClient()) { string apiUrl = sApiEndpoint + "/v1/events/places/" + placeID + "?size=" + numOfLogs + "&sort=id%2Cdesc"; string authHeader = "Bearer " + sAccessToken; CookieContainer cookieContainer = new CookieContainer(); HttpClientHandler handler = new HttpClientHandler { CookieContainer = cookieContainer }; // Set the JSON content client.DefaultRequestHeaders.Add("Authorization", authHeader); cookieContainer.Add(new Uri(sApiEndpoint), new Cookie("Authorization", authHeader)); HttpResponseMessage response = client.GetAsync(apiUrl).Result; if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); sLogEventResponse = responseBody; } else { string responseBody = await response.Content.ReadAsStringAsync(); var clueErrorResponse = ClueErrorResponse.FromJson(responseBody); string errorResponse = clueErrorResponse.Errors[0].Code + ":" + clueErrorResponse.Errors[0].Message; MessageBox.Show("c。\n" + errorResponse, "Error"); } } return sLogEventResponse; }
sLogEventResponse = contains the entire API response body in JSON format. You can then convert this JSON string to Array or List<>.
Sample Application
Event Explanation
- DEV_FACE_AUTH_SUCCESS - The user's face template is registered in CLUe server. Thus, it is successful when user authenticated from the device
- VENDOR_AUTH_SUCCESS - It means that the user's ID (example 64455 above) is registered and allowed access from the 3rd party system.
- DEV_DOOR_RELAY_ON - The relay of the device is turned ON. Door is unlocked.
- DEV_DOOR_RELAY_OFF - The relay of the device is turned OFF. Door is locked.
Sample Flow of Events for Authentication Success
Sample Flow of Events for Authentication Failed (CLUe Side)
Sample Flow of Events for Authentication Failed (3rd Party System side)