Introduction
This is the documentation for the HTTP API provided by KIWI.KI GmbH for remote unlocking and administration of doors. This API can be used for integration into existing systems and for application development.
You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs on the top right.
Pre-release Disclaimer
Stable releases of the KIWI API are forthcoming.
Getting Started
Getting a User Account
A user account is required for most interactions with the KIWI API. An account can be obtained by:
- Being given an account by an administrator or manager who is using Portal.
- Creating an account with the Mobile Web App.
- Creating an account using API endpoints. See Creating a New User
- Test accounts and permissions can be granted on request by the KIWI team. Send us an email to [email protected]
See KIWI Applications to learn more about apps available for user account administration.
Getting Permissions to a Door
A user account must be granted permissions to a door before that user can unlock it remotely or perform other actions with it using the API. Permissions can be granted by an administrator or manager using Portal.
See Permissions for more information.
Getting a session key
curl https://api.kiwi.ki/pre/session/ -d '{"username":"[email protected]", "password":"mypassword"}' -H 'Content-Type: application/json'
Reponse:
{
"status": "ok",
"result": {
"session": {
"username": "[email protected]",
"max_expires": "2017-04-03T14:45:32.954709+02:00",
"expires": "2017-01-11T14:45:32.954709+01:00",
"enabled": "2017-01-03T14:45:32.841411+01:00",
"organization_id": 42,
"user_id": 1234,
"session_key": "cda9341330b0bab64b713a866b24b477",
"account_verification": 11
},
"session_key": "cda9341330b0bab64b713a866b24b477"
}
}
A valid session key is a required parameter for most API requests. With a user account, a session key can be retrieved using the /pre/session/
endpoint:
Perform a POST
to https://api.kiwi.ki/pre/session/
with the payload in the form:
{"username": "[email protected]", "password": "my_password"}
Example session key: cda9341330b0bab64b713a866b24b477
See Authentication for more information.
Opening a door
curl -X POST "https://api.kiwi.ki/pre/sensors/123/act/open/?session_key=cda9341330b0bab64b713a866b24b477"
Reponse:
{
"status": "ok"
}
Each KIWI equipped door has an associated sensor, which can detect KIWI Kis and trigger unlocking of the door.
Perform a POST
to https://api.kiwi.ki/pre/sensors/<sensor_id>/act/open/?session_key=<session_key>
to unlock a door.
Where sensor_id
is the ID of the sensor connected to the door, and session_key
corresponds to a valid session obtained earlier with a username/password. See Open Door for more information.
See Sensors for how search and retrieve sensor IDs.
API Requests
Base URL
The base URL for making HTTP requests with the KIWI API is
Where /pre/
indicates Pre-release status.
HTTPS is required for all API requests.
Parameters
When making HTTP requests with the KIWI API, parameters can be passed in two ways:
Query String
For GET
requests, a query string must be used.
A query string can be appended to the request URL with the parameter names and values. E.g.
In this example the session_key
parameter is passed with the value “94be2d729ed71bf7d5860404e6d500e1” to the sensors endpoint.
Request Body
For POST
requests, parameters must be passed in the request body with the content type application/json
.
cURL example:
Where the -d
flag specifies the body, and -H
specifies the request headers.
Authentication
Before most API requests can be made, a login session must be started by providing a valid username and password. A session key will then be given back from the API, which can be used for authentication on further API requests.
Authentication with a session key covers general access to the API endpoints, but for controlling individual permissions to doors, see Permissions.
Get Session Key
curl https://api.kiwi.ki/pre/session/ -d '{"username":"[email protected]", "password":"mypassword"}' -H 'Content-Type: application/json'
import requests
login_credentials = dict(
username="myusername",
password="supersecretpassword")
response = requests.post(
"https://api.kiwi.ki/pre/session/",
json=login_credentials)
print(response.json())
Reponse:
{
"status": "ok",
"result": {
"session": {
"username": "myusername",
"max_expires": "2017-03-12T17:12:52.727104+01:00",
"expires": "2016-12-12T18:12:52.727104+01:00",
"enabled": "2016-12-12T17:12:52.613417+01:00",
"is_admin": false,
"user_id": 25,
"session_key": "5633238d67040b7316456e47ec5181e0",
"account_verification": 1
},
"session_key": "5633238d67040b7316456e47ec5181e0"
}
}
HTTP Request
POST /pre/session/
Query Parameters
Name | Type | Description | Example |
---|---|---|---|
username | string (required) |
The username for the user account, which is usually an email address. | [email protected] |
password | string (required) |
The password for the user account. |
Response
Field | Type | Description |
---|---|---|
username | string | The username of the authenticated user (usually an email address). |
max_expires | datetime | The maximum lifetime of the session in timezone aware ISO 8601 format. |
expires | datetime | The expiration time while inactive in timezone aware ISO 8601 format. |
enabled | datetime | The creation time of the session in timezone aware ISO 8601 format. |
is_admin | boolean | True only for KIWI staff with admin rights. |
user_id | integer | The user’s unique identifier. |
session_key | string | All further API requests that require authentication will need this value to be passed as session_key . |
account_verification | integer | Your verification level. |
Verification Level
Level | Description |
---|---|
0 | Uncompleted online registration. |
1 | Unverified account. |
2 | Unverified account with claimed Ki. |
11 | Verified online user account. |
12 | Verified offline (managed) user account. |
The result.session_key
is deprecated and should not be used. Use result.session.session_key
instead.
For more information about obtaining a user account, see this getting started section.
Permissions
For each sensor (door), permissions on that sensor control:
- Which users can unlock the door.
- Which permissions users can grant to other users to the door.
- Which users can be seen by other users.
Permission Type | Able to Grant | Description |
---|---|---|
Guest | (None) | The user is able to unlock the door, but cannot grant any other user permission to the door. |
Host | Guest | The user is able to unlock the door, and can grant other users Guest permission to the door (but no other permission type). |
Manager | Host, Guest | The user is able to unlock the door, and can grant other users Guest or Host permission to the door. |
Admin | Manager, Host, Guest | The user is able to unlock the door, and can grant other users Guest, Host or Manager permission to the door. |
Basic
curl -X POST -d \
'{
"users":["<username_1>", "<username_2>"],
"sensors":[<sensor_id_1>, <sensor_id_2>],
"permission":"<permission>",
}' \
-H 'Session-Key: <session_key>' \
'https://api.kiwi.ki/pre/permissions/user/sensor/'
Response:
{
"status": "ok",
"result": {
"permissions": [
123
],
"total_permissions": 1
}
}
POST /pre/users/
Headers
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
Parameters
Name | Type | Description | Example |
---|---|---|---|
permission | string (required) |
Permission one of IS_GUEST, IS_HOST, IS_MANAGER |
|
usernames | array (required) |
Array of usernames (string ) |
|
sensors | array (required) |
Array of sensor IDs (int ) |
Time based
curl -X POST -d \
'{
"users":["<username_1>", "<username_2>"],
"sensors":[<sensor_id_1>, <sensor_id_2>],
"permission":"<permission>",
"begins": "yyyy-mm-ddThh:MM",
"ends": "yyyy-mm-ddThh:MM",
"timeofday_begins": "hh:MM",
"timeofday_ends": "hh:MM",
"weekdays": "monday,tuesday,wednesday,thursday,friday,saturday,sunday"
}' \
-H 'Session-Key: <session_key>' \
'https://api.kiwi.ki/pre/permissions/user/sensor/'
Response:
{
"status": "ok",
"result": {
"permissions": [
123
],
"total_permissions": 1
}
}
POST /pre/users/
Headers
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
Parameters
Name | Type | Description | Example |
---|---|---|---|
permission | string (required) |
Permission one of IS_GUEST, IS_HOST, IS_MANAGER, IS_ADMIN |
IS_GUEST |
usernames | array (required) |
Array of usernames (string ) |
[“[email protected]”] |
sensors | array (required) |
Array of sensor IDs (int ) |
[1, 2] |
begins | datetime (optional) |
Date time format: yyyy-mm-ddThh:MM |
2019-03-01T10:00 |
end | datetime (optional) |
Date time format: yyyy-mm-ddThh:MM |
2019-04-01T10:00 |
timeofday_begins | time (optional) |
Time of day when the permission is active, format hh:MM |
10:00 |
timeofday_ends | time (optional) |
Time of day when the permission is no longer active, format hh:MM |
23:00 |
weekdays | string (optional) |
List of weekdays, comma separated (monday,tuesday ) |
“monday,thursday,friday” |
Addresses
curl https://api.kiwi.ki/pre/addresses/search/\?street\=Voltastr.\&number\=5\&plz\=13355
Reponse:
{
"status": "ok",
"result": {
"total_results": 0,
"results": [],
"exists": true
}
}
With this special endpoint, you can check if an address exists in our system. An existing address indicates that this building is already KIWI equipped.
the value "exists": true
tells you that a door sensor is available at this address.
Non-authenticated users are permitted to know the existence of sensors ("exists": true
) but may not be permitted to see details about those sensors. In this case an empty results list is returned.
GET /pre/addresses/search/
Parameter | Type | Description | Example |
---|---|---|---|
street | string |
Street name in Deutsche Post Data Factory Format | Voltastr. |
number | integer |
House or apartment number | 5 |
plz | integer |
ZIP code | 13355 |
Sensors
List Sensors
curl https://api.kiwi.ki/pre/sensors/?session_key=94be2d729ed71bf7d5860404e6d500e1
In some cases, you want to search for an Address but you don’t know the exact address format. Use the fuzzy search field combined with filters.
curl https://api.kiwi.ki/pre/sensors/\
?session_key=d89eed49cdb851431eacbff8d948927f\
&page_number=1&page_size=20\
&search=Volta\
&postal_code=13355\
&city=Berlin
import requests
doorlist_params = dict(
session_key="d89eed49cdb851431eacbff8d948927f",
page_number=1,
page_size=20,
search="Volta",
postal_code=13355,
city="Berlin",
)
response = requests.get(
"https://api.kiwi.ki/pre/sensors/",
params=doorlist_params
)
print(response.json())
Reponse:
{
"status": "ok",
"result": {
"order_by": "ASC",
"total_results": 1,
"page_size": 20,
"sort_by": "id",
"page_number": 1,
"sensors": [
{
"hardware_type": "DOOR",
"sensor_id": 9403,
"highest_permission": null,
"image": null,
"address": {
"city": "Berlin",
"specifier": "Tofus Apartment",
"country": "DE",
"state": "Berlin",
"street": "Voltastr. 11",
"postal_code": "13355",
"lat": 52.54189825,
"lng": 13.39018362,
"id": 4731
},
"sensor_name": null,
"is_owner": false,
"can_invite": false
}
]
}
}
Returns a list of sensors (doors) that the authenticated user has access to.
HTTP Request
GET /pre/sensors/
Parameters - Authentication
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
Parameters - Pagination / Sorting
Name | Type | Description | Example |
---|---|---|---|
sort_by | string (optional) |
Property to sort results by. (‘id’, 'distance’, 'specifier’, 'street’, or 'postal_code’) | street |
order_by | string (optional) |
Sorting direction ('asc’ or 'desc’) | desc |
page_size | integer (optional) |
The number of sensors to return. | 20 |
page_number | integer (optional) |
When page_size is given, specifies the page index. |
5 |
Parameters - Filtering
Name | Type | Description | Example |
---|---|---|---|
search | string (optional) |
Only include sensors that have a partial case-insensitive match to the given string for the 'specifier’, 'street’, 'postal_code’ or 'city’ properties. | Voltastr. 5 Berlin |
specifier | string (optional) |
Only include sensors that have a case-insensitive match to the given string for the 'specifier’ property. | Keller |
street | string (optional) |
Only include sensors that have a case-insensitive match to the given string for the 'street’ property. | Voltastr. 5 |
city | string (optional) |
Only include sensors that have a case-insensitive match to the given string for the 'city’ property. | Berlin |
state | string (optional) |
Only include sensors that have a case-insensitive match to the given string for the 'state’ property. | Niedersachsen |
postal_code | string (optional) |
Only include sensors with the given postal code. | 13355 |
permission | string (optional) |
Only include sensors for which the authenticated user’s permission type to the sensor is equal or greater than the given type. Possible values: 'IS_GUEST’, 'IS_HOST’, 'IS_MANAGER’, 'IS_ADMIN’. | IS_HOST |
Parameters - Geolocation
Name | Type | Description | Example |
---|---|---|---|
lat | float (optional) |
Latitude. When lat and lng are specified, the list of sensors returned will be sorted by their proximity to the given geolocation. |
52.508125 |
lng | float (optional) |
Longitude. When lat and lng are specified, the list of sensors returned will be sorted by their proximity to the given geolocation. |
13.460401 |
max_distance | float (optional) |
When lat and lng are specified, only sensors that are within the given distance (in kilometers) will be returned. |
0.5 |
Get Sensor Details
curl https://api.kiwi.ki/pre/sensors/9403/?session_key=94be2d729ed71bf7d5860404e6d500e1
import requests
# use our example door
sensor_id = 9403
session_key = "94be2d729ed71bf7d5860404e6d500e1"
response = request.get(
"https://api.kiwi.ki/pre/sensors/%s/" % sensor_id,
params={"session_key":session_key}
)
print(response.json())
{
"status": "ok",
"result": {
"sensor": {
"hardware_type": "DOOR",
"sensor_id": 9403,
"highest_permission": null,
"image": null,
"address": {
"city": "Berlin",
"specifier": "Tofus Apartment",
"country": "DE",
"state": "Berlin",
"street": "Voltastr. 5",
"postal_code": "13355",
"lat": 52.54189825,
"lng": 13.39018362,
"id": 4731
},
"sensor_name": null,
"is_owner": false,
"can_invite": false
}
}
HTTP Request
GET /pre/sensors/<sensor_id>/
Parameters
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
sensor_id | integer (required) |
The unique ID of the sensor. | 9403 |
Open Door
curl -X POST https://api.kiwi.ki/pre/sensors/9403/act/open/?session_key=94be2d729ed71bf7d5860404e6d500e1
import requests
# assuming you already have a session_key
session_key = "94be2d729ed71bf7d5860404e6d500e1"
sensor_id = 9403
resonse = requests.post(
"https://api.kiwi.ki/pre/sensors/%s/act/open?session_key=%s" % (sensor_id, session_key)
)
print(response.json())
{
"status": "ok"
}
Given authentication and sufficient permissions, allows unlocking of a door connected to a sensor.
HTTP Request
POST /pre/sensors/<sensor_id>/act/open
Parameters
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
sensor_id | integer (required) |
The unique ID of the sensor. | 9403 |
Assign Custom Name to Sensor
curl 'https://api.kiwi.ki/pre/fnames/sensor/9403/' \
-H 'Content-Type: application/json; charset=UTF-8' \
-d '{"session_key":"94be2d729ed71bf7d5860404e6d500e1","friendly_name":"foobar"}'
import requests
session_key = "94be2d729ed71bf7d5860404e6d500e1"
sensor_id = 9403
name_parameter = {
"friendly_name": "foobar"
}
response = requests.post(
"https://api.kiwi.ki/pre/fnames/sensor/%s/?session_key=%s" % (sensor_id, session_key),
data=name_parameter
)
print(response.json())
{
"status": "ok",
"result": {
"sensor_id": "9403",
"fname": "My Red Door"
}
}
Assigns a custom name to a sensor. Each user may assign their own names to each sensor; these custom names are visible only to the users that created them.
Custom names will appear in the sensor_name
fields returned by the /sensors and /sensors/<sensor_id> endpoints.
You can also search for sensors by their custom names using this endpoint.
POST /pre/fnames/sensor/<sensor_id>/
Parameters
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
sensor_id | integer (required) |
The unique ID of the sensor. | 9403 |
fname | string (required) |
A custom name to give to the sensor. | My Red Door |
Search for Sensor by Custom Name
curl 'https://api.kiwi.ki/pre/sensors/by_fname/?session_key=94be2d729ed71bf7d5860404e6d500e1&friendly_name=MyRedDoor'
{
"status": "ok",
"result": {
"total_results": 1,
"sensors": [
{
"highest_permission": "IS_HOST",
"hardware_type": "DOOR",
"sensor_id": 1,
"is_owner": true,
"address": {
"city": "Berlin",
"specifier": "Tofus Apartment",
"country": "DE",
"state": "Berlin",
"street": "Voltastr. 5",
"postal_code": "13355",
"lat": 52.54189825,
"lng": 13.39018362,
},
"sensor_name": "MyRedDoor",
"can_invite": true
}
]
}
}
Find sensors by the custom names you have assigned to them.
This endpoint returns a list of all sensors whose friendly_name
matches the
given name exactly and case-sensitively.
GET /pre/sensors/by_fname/
Parameters
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
friendly_name | string (required) |
Sensors whose friendly_name matches the given value (case-sensitive) will be returned | My Red Door |
Users
Get User Details
curl https://api.kiwi.ki/pre/users/2664/?session_key=178d3d01a1872f58573183833897a732
Reponse:
{
"status": "ok",
"result": {
"user": {
"username": "[email protected]",
"contact": {
"name": "Foo",
"segment_id": "10",
"lastname": "Barrington",
"title": "Mr",
"customer_number": "10DE1600002664",
"country": "DE"
},
"user_id": 2664,
"organization_id": 61
}
}
}
GET /pre/users/<user_id>/
Parameters
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
user_id | integer (required) |
The unique ID for the user. Note that the session endpoint returns the user_id . |
123 |
Create a new User
curl -X POST -d \
'{
session_key":"178d3d01a1872f58573183833897a732",
"name":"Foo",
"lastname":"Barrington",
"title":"Mr",
"segment_id":"10",
"country":"DE",
"i_have_read_and_accepted_kiwidotki_agb":true,
"lang":"en",
"password":"supersecretpassword",
"email":"[email protected]"
}' https://api.kiwi.ki/pre/users/
Reponse:
{
"status": "ok",
"result": {
"user": {
"username": "[email protected]",
"user_id": 2953,
"email": "[email protected]",
"myself_group_id": 21637
}
}
}
POST /pre/users/
Parameters
Name | Type | Description | Example |
---|---|---|---|
session_key | string (required) |
A valid API session key. See Authentication. | 5633238d67040b7316456e47ec5181e0 |
string (required) |
The email address of the new user. This will become the user’s username. | [email protected] | |
password | string (required) |
The new password for the user. | |
lang | string (optional) |
The default language to use for correspondence and app display with this user. Defaults to ‘de’. | en |
country | string (optional) |
The country of residence for the user. | DE |
segment_id | string (optional) |
Marks which customer segment the user belongs to. | 10 |
Terms and Conditions (AGB)
The KIWI.KI AGBs must be accepted for user account creation. The following parameter is mandatory:
Name | Type | Description | Example |
---|---|---|---|
i_have_read_and_accepted_kiwidotki_agb | boolean (required) |
'true’ must be given, or the account creation request will be rejected. | true |
The user is now created in the system, but not verified yet. To use it, you need to verify the email address. For that, click on the verification link you just received via email.
Errors
The KIWI.KI API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request – Your request is buggy. Check the parameters |
401 | Unauthorized – Your are not logged in. Authenticate please. |
403 | Forbidden – The endpoint you requested is for administrators only |
404 | Not Found – The specified resource could not be found |
405 | Method Not Allowed – You tried to access a resource with an invalid method |
406 | Not Acceptable – You requested a format that isn’t json |
410 | Gone – The resource requested has been removed from our servers |
418 | I’m a teapot |
429 | Too Many Requests – Rate of requests exceeded limit. |
500 | Internal Server Error – We had a problem with our server. Try again later. |
503 | Service Unavailable – We’re temporarially offline for maintenance. Please try again later. |