

# Devices API Reference

API endpoints for managing devices.

## Get Devices

`GET` `https://api.igloohome.co/home/devices`

Returns a list of devices paired to the account. Devices include locks, as well as non-lock devices.

|Device Type|
|--|
|Lock|
|Keypad|
|Bridge|
|Fob|

### Query Parameters

- **`limit`** `number<int32>`\
  Number of objects to return, from 1 to 300. Defaults to 100.
  - Constraints: `>= 1`, `<= 300`
  - Default: `100`
  - Example: `30`
- **`cursor`** `string`\
  The pagination cursor. `cursor` is a string ID that marks your place in the list. For instance, if you make a list request and receive 100 objects, with `nextCursor` of `2sThyA1jii6WmTo3j`, your next call can include `cursor=2sThyA1jii6WmTo3j` in order to fetch the next page of the list.
- **`sort`** `string`\
  Order in which to return objects. Defaults to `desc`.
  - Default: `desc`
  - Allowed values: `asc`, `desc`

### Request Example

```bash
curl -X GET "https://api.igloohome.co/home/devices?limit=value&cursor=value&sort=value" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices?limit=value&cursor=value&sort=value"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices?limit=value&cursor=value&sort=value", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
  }
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
params = {
    "limit": "value",
    "cursor": "value",
    "sort": "value"
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices?limit=value&cursor=value&sort=value",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json"
    ]
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices?limit=value&cursor=value&sort=value")
    .method("GET", null)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices?limit=value&cursor=value&sort=value")!)
request.httpMethod = "GET"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 OK`
`400 Bad Request`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/get-devices'`
`500 Internal Server Error`

**Response body — `200`:**

- **`nextCursor`** `string`\
  A string pointing to the next page of results. Empty string indicates you reached the end of the list
  - Example: `2sThyA1jii6WmTo3j`
- **`payload`** `array of object`\
  An array containing the return devices
  - **`id`** `string`\
    Internal batch identifier of the device
    - Example: `2rqQx4Riasw3Rs6db01`
  - **`type`** `string`\
    Device Type
    - Example: `Keypad`
  - **`deviceId`** `string`\
    Unique Identifier of the device
    - Example: `EK1X013f300d`
  - **`deviceName`** `string`\
    Name of the device
    - Example: `My keypad 1`
  - **`batteryLevel`** `integer`\
    Battery level of the device
    - Example: `100`
  - **`pairedAt`** `string<date-time>`\
    Pairing date
    - Example: `2022-05-30T00:00:00+08:00`
  - **`homeId`** `array of string`\
    Associated homes or properties. Populated as full property objects when you pass `expand=homeId`.
    - Example: `["2rqQx4Riasw3Rs6db"]`
  - **`linkedDevices`** `array of object`\
    Device(s) linked to this device
    - Example: `[{"type":"Lock"},{"deviceId":"IGP102c1854a"}]`
    - **`id`** `string`\
      Internal batch identifier of the linked device
    - **`type`** `string`
    - **`deviceId`** `string`

**Response body — `400`:**

- **`error`** `string`

**Response body — `402`:**

- **`error`** `string`

**Example response — `200`:**

```json
{
  "nextCursor": "22j3230ids0idsa0d",
  "payload": [
    {
      "batteryLevel": 100,
      "deviceId": "EK1X013f300d",
      "deviceName": "Keypad",
      "homeId": [
        "2rqQx4Riasw3Rs6db"
      ],
      "linkedDevices": [
        {
          "deviceId": "IGP102c1854a",
          "type": "Lock"
        }
      ],
      "pairedAt": "2022-06-30T17:00:00+08:00",
      "type": "Keypad"
    }
  ]
}
```

**Example response — `400`:**

```json
{
  "error": "'cursor' cannot be empty string"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

## Get Devices Supporting AlgoPIN

`GET` `https://api.igloohome.co/home/devices/support-pins`

Returns a list of devices paired to the account that support AlgoPIN codes. Same
shape and filters as [Get Devices](/home/api_devices#get-devices), restricted to
AlgoPIN-capable SKUs.

### Query Parameters

- **`limit`** `number<int32>`\
  Number of objects to return, from 1 to 300. Defaults to 100.
  - Constraints: `>= 1`, `<= 300`
  - Default: `100`
  - Example: `30`
- **`cursor`** `string`\
  The pagination cursor. `cursor` is a string ID that marks your place in the list. For instance, if you make a list request and receive 100 objects, with `nextCursor` of `2sThyA1jii6WmTo3j`, your next call can include `cursor=2sThyA1jii6WmTo3j` in order to fetch the next page of the list.
- **`sort`** `string`\
  Order in which to return objects. Defaults to `desc`.
  - Default: `desc`
  - Allowed values: `asc`, `desc`

### Request Example

```bash
curl -X GET "https://api.igloohome.co/home/devices/support-pins?limit=value&cursor=value&sort=value" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices/support-pins?limit=value&cursor=value&sort=value"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices/support-pins?limit=value&cursor=value&sort=value", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
  }
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices/support-pins"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
params = {
    "limit": "value",
    "cursor": "value",
    "sort": "value"
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices/support-pins?limit=value&cursor=value&sort=value",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json"
    ]
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices/support-pins?limit=value&cursor=value&sort=value")
    .method("GET", null)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices/support-pins?limit=value&cursor=value&sort=value")!)
request.httpMethod = "GET"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 OK`
`400 Bad Request. Same validation as [Get Devices](/home/api_devices#get-devices).`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/get-devices'`
`500 Internal Server Error`

**Response body — `200`:**

- **`nextCursor`** `string`\
  A string pointing to the next page of results. Empty string indicates you reached the end of the list
- **`payload`** `array of object`
  - **`id`** `string`
  - **`type`** `string`
  - **`deviceId`** `string`
  - **`deviceName`** `string`
  - **`batteryLevel`** `integer`
  - **`pairedAt`** `string<date-time>`
  - **`homeId`** `array of string`
  - **`linkedDevices`** `array of object`
    - **`id`** `string`
    - **`type`** `string`
    - **`deviceId`** `string`

**Response body — `400`:**

- **`error`** `string`

**Response body — `402`:**

- **`error`** `string`

**Example response — `200`:**

```json
{
  "nextCursor": "",
  "payload": [
    {
      "batteryLevel": 87,
      "deviceId": "IGP102c1854a",
      "deviceName": "Front Door Lock",
      "homeId": [
        "2rqQx4Riasw3Rs6db"
      ],
      "id": "2rqQx4Riasw3Rs6db01",
      "linkedDevices": [],
      "pairedAt": "2023-06-15T14:30:00+08:00",
      "type": "Lock"
    }
  ]
}
```

**Example response — `400`:**

```json
{
  "error": "'limit' must be between 1 to 300 inclusive"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

## Get Device Details

`GET` `https://api.igloohome.co/home/devices/{deviceId}`

Returns device details.

`lockStatus` is only populated for a `Lock` device that is linked to a bridge.
`admin_key`/`lockRef` are only populated when the corresponding query params are passed.

### Path Parameters

| Parameter | Type | Required |
| --- | --- | --- |
| deviceId | string | Yes |

### Request Example

```bash
curl -X GET "https://api.igloohome.co/home/devices/{deviceId}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices/{deviceId}"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices/{deviceId}", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
  }
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices/{deviceId}"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices/{deviceId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json"
    ]
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices/{deviceId}")
    .method("GET", null)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices/{deviceId}")!)
request.httpMethod = "GET"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 OK`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/get-devices'`
`404 '{ message: 'not found device' }'`
`409 Conflict. The device's property record is missing a timezone (data integrity guard). '{ message: 'timezone is not found on property' }'`
`500 Internal Server Error`

**Response body — `200`:**

- **`id`** `string`\
  Internal batch identifier of the device
  - Example: `2rqQx4Riasw3Rs6db01`
- **`type`** `string`\
  Device Type
  - Example: `Keypad`
- **`deviceId`** `string`\
  Unique Identifier of the device
  - Example: `EK1X013f300d`
- **`deviceName`** `string`\
  Name of the device
  - Example: `My keypad 1`
- **`batteryLevel`** `integer`\
  Battery level of the device
  - Example: `100`
- **`pairedAt`** `string<date-time>`\
  Pairing date
  - Example: `2022-05-30T00:00:00+08:00`
- **`lockStatus`** `string`\
  Current lock status. Only populated for a `Lock` device that is linked to a bridge.
  - Example: `LOCKED`
- **`homeId`** `array of string`\
  Associated home/property(s)
  - Example: `["2rqQx4Riasw3Rs6db"]`
- **`linkedDevices`** `array of object`\
  Device(s) linked to this device
  - Example: `[{"type":"Lock"},{"deviceId":"IGP102c1854a"}]`
  - **`type`** `string`
  - **`deviceId`** `string`
- **`lastSync`** `string<date-time>`\
  Timestamp of the last activity sync from the device
- **`admin_key`** `string`\
  Obfuscated admin key material. Only returned for G2 devices when `admin_key=true`/`1` is passed.
- **`lockRef`** `string`\
  Internal database reference of the device. Only returned when `lock_id=true`/`1` is passed.

**Response body — `402`:**

- **`error`** `string`

**Response body — `404`:**

- **`message`** `string`

**Response body — `409`:**

- **`message`** `string`

**Example response — `200`:**

```json
{
  "batteryLevel": 20,
  "deviceId": "EK1X013f300d",
  "deviceName": "My keypad 1",
  "homeId": [
    "2rqQx4Riasw3Rs6db"
  ],
  "id": "2rqQx4Riasw3Rs6db01",
  "lastSync": "2022-05-30T00:00:00+08:00",
  "linkedDevices": [],
  "pairedAt": "2021-07-03T12:00:00+08:00",
  "type": "Keypad"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

**Example response — `404`:**

```json
{
  "message": "not found device"
}
```

**Example response — `409`:**

```json
{
  "message": "timezone is not found on property"
}
```

## Configure Device Details

`PUT` `https://api.igloohome.co/home/devices/{deviceId}`

Configures device settings.

The API rejects `batteryLevel` with `400` on device SKUs that don't support
battery-level reporting.

### Path Parameters

| Parameter | Type | Required |
| --- | --- | --- |
| deviceId | string | Yes |

### Body Parameters

Content-Type: `application/json`

- **`batteryLevel`** `integer<int32>`\
  **batteryLevel** defines the level of battery detail reported by the lock. `null` is accepted and ignored: nothing is updated and `200` is returned.

### Request Example

```bash
curl -X PUT "https://api.igloohome.co/home/devices/{deviceId}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "batteryLevel": "value"
  }'
```

```go
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices/{deviceId}"
	payload := []byte(`{
		"batteryLevel": "value"
	}`)

	req, _ := http.NewRequest("PUT", url, bytes.NewBuffer(payload))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices/{deviceId}", {
  method: "PUT",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "batteryLevel": "value"
  })
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices/{deviceId}"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
payload = {
    "batteryLevel": "value"
}
response = requests.put(url, headers=headers, json=payload)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices/{deviceId}",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "PUT",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json",
        "Content-Type: application/json"
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "batteryLevel" => "value"
    ])
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val mediaType = "application/json".toMediaType()
val body = """
    {
        "batteryLevel": "value"
    }
""".trimIndent().toRequestBody(mediaType)

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices/{deviceId}")
    .method("PUT", body)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .addHeader("Content-Type", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices/{deviceId}")!)
request.httpMethod = "PUT"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let payload: [String: Any] = [
    "batteryLevel": "value"
]
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 Settings updated.`
`400 Bad Request`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/update-device'`
`404 Not Found`
`409 Conflict. The device's property record is missing a timezone (data integrity guard). '{ message: 'timezone is not found on property' }'`
`415 Unsupported Media Type`
`500 Internal Server Error`

**Response body — `200`:**

- **`message`** `string`
  - Example: `Successfully`

**Response body — `400`:**

- **`error`** `string`

**Response body — `402`:**

- **`error`** `string`

**Response body — `404`:**

- **`error`** `string`
- **`message`** `string`

**Response body — `409`:**

- **`message`** `string`

**Example response — `200`:**

```json
{
  "message": "Successfully"
}
```

**Example response — `400`:**

```json
{
  "error": "The BatteryLevel is too high! It must be at least 100"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

**Example response — `404`:**

```json
{
  "message": "not found device"
}
```

**Example response — `409`:**

```json
{
  "message": "timezone is not found on property"
}
```

## Get Device Activity Logs

`GET` `https://api.igloohome.co/home/devices/{deviceId}/activity`

Returns a paginated list of activity logs recorded for a device.

### Path Parameters

| Parameter | Type | Required |
| --- | --- | --- |
| deviceId | string | Yes |

### Query Parameters

- **`startDate`** `string<date-time>`\
  Only return activity logs on or after this date
- **`endDate`** `string<date-time>`\
  Only return activity logs up to and including this date
- **`locale`** `string`\
  Locale for the human-readable `description` field. Must be one of the supported locale codes, otherwise the API returns `400`. Two of those codes (`ko`, `ru`) are accepted but not yet translated. They fall back to `en` instead of returning an error.
  - Default: `en`
- **`limit`** `number<int32>`\
  Number of objects to return, from 1 to 300. Defaults to 100.
  - Constraints: `>= 1`, `<= 300`
  - Default: `100`
  - Example: `30`
- **`cursor`** `string`\
  The pagination cursor. `cursor` is a string ID that marks your place in the list. For instance, if you make a list request and receive 100 objects, with `nextCursor` of `2sThyA1jii6WmTo3j`, your next call can include `cursor=2sThyA1jii6WmTo3j` in order to fetch the next page of the list.
- **`sort`** `string`\
  Order in which to return objects. Defaults to `desc`.
  - Default: `desc`
  - Allowed values: `asc`, `desc`

### Request Example

```bash
curl -X GET "https://api.igloohome.co/home/devices/{deviceId}/activity?startDate=value&endDate=value&locale=value&limit=value&cursor=value&sort=value" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices/{deviceId}/activity?startDate=value&endDate=value&locale=value&limit=value&cursor=value&sort=value"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices/{deviceId}/activity?startDate=value&endDate=value&locale=value&limit=value&cursor=value&sort=value", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
  }
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices/{deviceId}/activity"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
params = {
    "startDate": "value",
    "endDate": "value",
    "locale": "value",
    "limit": "value",
    "cursor": "value",
    "sort": "value"
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices/{deviceId}/activity?startDate=value&endDate=value&locale=value&limit=value&cursor=value&sort=value",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json"
    ]
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices/{deviceId}/activity?startDate=value&endDate=value&locale=value&limit=value&cursor=value&sort=value")
    .method("GET", null)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices/{deviceId}/activity?startDate=value&endDate=value&locale=value&limit=value&cursor=value&sort=value")!)
request.httpMethod = "GET"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 OK`
`400 Bad Request. Invalid 'locale'/'limit'/'cursor'/'sort'.`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/get-device-activity'`
`404 '{ message: 'not found device' }' or '{ message: 'not found property' }'`
`409 Conflict. The device's property record is missing a timezone (data integrity guard). '{ message: 'timezone is not found on property' }'`
`500 Internal Server Error`

**Response body — `200`:**

- **`nextCursor`** `string`\
  A string pointing to the next page of results. Empty string indicates you reached the end of the list
- **`payload`** `array of object`\
  An array containing activity log entries
  - **`activityType`** `string`
  - **`description`** `string`\
    Human-readable, locale-translated description of the activity
  - **`activityTimeAt`** `string<date-time>`\
    Local time the activity occurred (alias of `localActionAt`)

**Response body — `400`:**

- **`error`** `string`

**Response body — `402`:**

- **`error`** `string`

**Response body — `404`:**

- **`message`** `string`

**Response body — `409`:**

- **`message`** `string`

**Example response — `200`:**

```json
{
  "nextCursor": "65a7d4c8b2c9f1e2d3a4b5c6",
  "payload": [
    {
      "activityTimeAt": "2024-01-15T14:30:00+08:00",
      "activityType": "UNLOCK",
      "description": "Unlocked by keypad PIN"
    },
    {
      "activityTimeAt": "2024-01-15T13:45:00+08:00",
      "activityType": "LOCK",
      "description": "Locked by bluetooth key"
    }
  ]
}
```

**Example response — `400`:**

```json
{
  "error": "'limit' must be between 1 to 300 inclusive"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

**Example response — `404`:**

```json
{
  "message": "not found device"
}
```

**Example response — `409`:**

```json
{
  "message": "timezone is not found on property"
}
```

## Push Device Activity Logs

`POST` `https://api.igloohome.co/home/devices/{deviceId}/activity`

Ingests raw activity logs synced off a device (e.g. by a bridge or app). Each
item in `logsPayload` is a JSON-serialized log entry.

### Path Parameters

| Parameter | Type | Required |
| --- | --- | --- |
| deviceId | string | Yes |

### Body Parameters

Content-Type: `application/json`

- **`logsPayload`** `array of string` *required*\
  Array of JSON-serialized log entry strings, each with `log` and `bluetoothDeviceName` fields

### Request Example

```bash
curl -X POST "https://api.igloohome.co/home/devices/{deviceId}/activity" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "logsPayload": "value"
  }'
```

```go
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices/{deviceId}/activity"
	payload := []byte(`{
		"logsPayload": "value"
	}`)

	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices/{deviceId}/activity", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "logsPayload": "value"
  })
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices/{deviceId}/activity"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
payload = {
    "logsPayload": "value"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices/{deviceId}/activity",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json",
        "Content-Type: application/json"
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "logsPayload" => "value"
    ])
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val mediaType = "application/json".toMediaType()
val body = """
    {
        "logsPayload": "value"
    }
""".trimIndent().toRequestBody(mediaType)

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices/{deviceId}/activity")
    .method("POST", body)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .addHeader("Content-Type", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices/{deviceId}/activity")!)
request.httpMethod = "POST"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let payload: [String: Any] = [
    "logsPayload": "value"
]
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 OK`
`400 '{ error: "\"logsPayload\" is required" }'`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/store-device-activity'`
`404 '{ message: 'not found device' }' or '{ message: 'not found property' }'`
`409 Conflict. The device's property record is missing a timezone (data integrity guard). '{ message: 'timezone is not found on property' }'`
`415 Unsupported Media Type`
`500 Internal Server Error`

**Response body — `200`:**

- **`message`** `string`
  - Example: `Successfully.`

**Response body — `400`:**

- **`error`** `string`

**Response body — `402`:**

- **`error`** `string`

**Response body — `404`:**

- **`message`** `string`

**Response body — `409`:**

- **`message`** `string`

**Example response — `200`:**

```json
{
  "message": "Successfully."
}
```

**Example response — `400`:**

```json
{
  "error": "\"logsPayload\" is required"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

**Example response — `404`:**

```json
{
  "message": "not found device"
}
```

**Example response — `409`:**

```json
{
  "message": "timezone is not found on property"
}
```

## Get Master PIN

`GET` `https://api.igloohome.co/home/devices/{deviceId}/masterpin`

Returns the master pin of the given device. Supports `lock` and `keypad` devices only.

|Device Type|
|--|
|Lock|
|Keypad|

### Path Parameters

| Parameter | Type | Required |
| --- | --- | --- |
| deviceId | string | Yes |

### Request Example

```bash
curl -X GET "https://api.igloohome.co/home/devices/{deviceId}/masterpin" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.igloohome.co/home/devices/{deviceId}/masterpin"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```javascript
const res = await fetch("https://api.igloohome.co/home/devices/{deviceId}/masterpin", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
  }
});

const data = await res.json();
console.log(data);
```

```python
import requests

url = "https://api.igloohome.co/home/devices/{deviceId}/masterpin"
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())
```

```php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.igloohome.co/home/devices/{deviceId}/masterpin",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_ACCESS_TOKEN",
        "Accept: application/json"
    ]
]);

$response = curl_exec($curl);
curl_close($curl);

echo $response;
```

```kotlin
val client = OkHttpClient()

val request = Request.Builder()
    .url("https://api.igloohome.co/home/devices/{deviceId}/masterpin")
    .method("GET", null)
    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
    .addHeader("Accept", "application/json")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string())
```

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.igloohome.co/home/devices/{deviceId}/masterpin")!)
request.httpMethod = "GET"
request.setValue("Bearer YOUR_ACCESS_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        print(String(data: data, encoding: .utf8) ?? "")
    }
}
task.resume()
```

### Responses

`200 OK`
`401 Unauthorized, invalid or expired authorization token`
`402 Response`
`403 Forbidden, accessToken scope must contain 'igloohomeapi/get-master-pin'`
`404 '{ message: 'not found device' }' or '{ message: 'not found property' }'`
`409 Conflict. The device's property record is missing a timezone (data integrity guard). '{ message: 'timezone is not found on property' }'`
`500 Internal Server Error`

**Response body — `200`:**

- **`pin`** `string`\
  Master pin
  - Example: `49667198`

**Response body — `402`:**

- **`error`** `string`

**Response body — `404`:**

- **`message`** `string`

**Response body — `409`:**

- **`message`** `string`

**Example response — `200`:**

```json
{
  "pin": "49667198"
}
```

**Example response — `402`:**

```json
{
  "error": "30 days igloohome API trial has ended"
}
```

**Example response — `404`:**

```json
{
  "message": "not found device"
}
```

**Example response — `409`:**

```json
{
  "message": "timezone is not found on property"
}
```

