REST API#
Heedy’s REST API allows programmatic access to backend data and functionality. Heedy plugins are also encouraged to add their own functionality at /api/{plugin_name}
.
This document details the API that comes built-in to heedy by default.
Errors#
Each request returns either the requested resource as JSON, or, upon failure, returns a 4xx
error code,
with the following json response body:
{
// An error type
"error": "not_found",
// Text description of the error
"error_description": "The given user was not found",
// ID of the request
"id": "bpqirkjqfqj3m0sqttf0"
}
API#
Users#
/api/users
GET
Returns a list of users in the heedy instance that are accessible with the given access token.URL Params
icon (boolean,false) - whether or not to include each user’s icon.
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/users
[{"username": "myuser", ... }, ... ]
POST
Create a new user. Only accessible from plugins and admin users.Body
username (string, required) - the username of the user
password (string, required) - the user’s password
name (string,””) - the user’s full name
description (string,””) - the user’s description
icon (string,””) - user’s icon, base64 urlencoded
public_read (boolean,false) - whether the user is visible to the public.
users_read (boolean,false) - whether the user is visible to other users.
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--header "Content-Type: application/json" \
--request POST \
--data '{"username":"user2","password":"xyz"}' \
http://localhost:1324/api/users
{"result":"ok"}
/api/users/{username}
GET
Returns the user with the given username.URL Params
icon (boolean,false) - whether or not to include the user’s icon.
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/users/myuser?icon=true
{
"username":"myuser",
"name":"",
"description":"",
"icon":"",
"public_read":false,
"users_read":false
}
PATCH
Updates the user with the included fields.Body
password (string,null) - the user’s password
name (string,null) - the user’s full name
description (string,null) - the user’s description
icon (string,null) - user’s icon, base64 urlencoded
public_read (boolean,null) - whether the user is visible to the public.
users_read (boolean,null) - whether the user is visible to other users.
Example
curl --header "Authorization: Bearer MYTOKEN" \
--header "Content-Type: application/json" \
--request PATCH \
--data '{"description":"A new user description!"}' \
http://localhost:1324/api/users/myuser
{"result":"ok"}
DELETE
Deletes the user with the given username, and all of the user's data.Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request DELETE \
http://localhost:1324/api/users/myuser
{"result":"ok"}
Apps#
/api/apps
GET
Returns a list of apps in the heedy instance that satisfy the given constraints, and are accessible with the given access token. A user only has access to apps belonging to the user, so when querying apps from the frontend or an app, you will only get the user's apps.URL Params
icon (boolean,false) - whether or not to include each app’s icon.
token (boolean,false) - whether or not to include each app’s access token.
owner (string,null) - limit results to the apps belonging to the given username
plugin (string,null) - limit results to apps with the given plugin key
enabled (boolean,null) - limit results to apps that are enabled/disabled (true/false)
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/apps?owner=myuser
[{"id": "051942...", ... }, ... ]
POST
Create a new app. Only accessible from plugins and users. If authenticated as a user, the owner parameter is optional. Returns the created app, subject to query URL params identical to a GET request for the app ID.Body
name (string,required) - the app’s name
owner (string,required) - the user to own the app. Automatically set to the current user when authenticated as a user.
description (string,””) - the app’s description
icon (string,””) - app’s icon, base64 urlencoded
plugin (string,””) - the app’s plugin key.
enabled (boolean,true) - whether the app’s access token is active
scope (string,””) - the scopes given to the app, each separated by a space.
settings (object,{}) - the app’s settings
settings_schema (object,{}) - the json schema for the app’s settings.
access_token (string) - If set to empty string, the app will be created without an access token. Otherwise (and by default), the app will have a randomly generated access token (any other string value of access_token is ignored).
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--header "Content-Type: application/json" \
--request POST \
--data '{"name":"My App","owner": "myuser"}' \
http://localhost:1324/api/apps
{
"id":"0519420b-e3cf-463f-b794-2adb440bfb9f",
"name":"My App",
"description":"",
"owner":"myuser",
"enabled":true,
"created_date":"2020-03-21",
"last_access_date":null,
"scope":"",
"settings":{},
"settings_schema":{}
}
/api/apps/{appid}
GET
Returns the app with the given IDURL Params
icon (boolean,false) - whether or not to include the app’s icon.
token (boolean,false) - whether or not to include the app’s access token.
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/apps/0519420b-e3cf-463f-b794-2adb440bfb9f
{
"id": "0519420b-e3cf-463f-b794-2adb440bfb9f",
"name": "My App",
"description": "",
"owner": "myuser",
"enabled": true,
"created_date": "2020-03-21",
"last_access_date": null,
"scope": "",
"settings": {},
"settings_schema": {}
}
PATCH
Updates the app with the included fields.Body
name (string,null) - the app’s full name
description (string,null) - the app’s description
icon (string,null) - app’s icon, base64 urlencoded
plugin (string,null) - the app’s plugin key.
enabled (boolean,null) - whether the app’s access token is active
scope (string,null) - the scopes given to the app, each separated by a space.
settings (object,null) - the app’s settings
settings_schema (object,null) - the json schema for the app’s settings.
access_token (string,null) - If set to empty string, the access token will be removed. Otherwise, if given a value, the app will generate a new random token (the value is ignored).
Example
curl --header "Authorization: Bearer MYTOKEN" \
--header "Content-Type: application/json" \
--request PATCH \
--data '{"description":"A new app description!"}' \
http://localhost:1324/api/apps/0519420b-e3cf-463f-b794-2adb440bfb9f
{"result":"ok"}
Since updating an access token randomly generates a new value, if the token was updated, it will be returned as part of the result.
{"result":"ok","access_token":"sdf43ri3i3g4j3ook"}
DELETE
Deletes the given app, and all of its data, including objects it manages.Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request DELETE \
http://localhost:1324/api/apps/0519420b-e3cf-463f-b794-2adb440bfb9f
{"result":"ok"}
Objects#
Heedy objects are special, since each object type has its own API. This section first describes the general object API that is valid for all object types, then it describes the additional API for objects of the type timeseries.
/api/objects
GET
Returns a list of objects in the heedy instance satisfying the given constraints, and accessible to the authenticated entity.URL Params
icon (boolean,false) - whether or not to include each object’s icon.
owner (string,null) - limit results to the objects belonging to the given username
app (string,null) - limit results to objects belonging to the given app
key (string,null) - limit results to objects with the given key
tags (string,null) - limit results to objects which each include all the given tags
type (string,null) - limit results to objects of the given type
limit (int,null) - set a maximum number of results to return
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/objects?owner=myuser
[{"id": "1a1f624...", ... }, ... ]
POST
Create a new object of the given type. Unless owner/app is set, the object will belong to the authenticated entity.Body
name (string,required) - the object’s name
type (string,required) - the object’s type
owner (string,current_user) - the user to own the object.
app (string,current_app/null) - the app to own the object.
description (string,””) - the object’s description
icon (string,””) - object’s icon, base64 urlencoded
tags (string,””) - a set of space-separated tags to give the object
key (string,null) - a key to give the object for easy programmatic access (only objects belonging to apps can have keys)
owner_scope (string,”*”) - the set of space-separated scopes to give the object’s owner, if the object belongs to an app. “*” means all scopes.
meta (object,{}) - object metadata. Each object type defines its own metadata.
Example
curl --header "Authorization: Bearer MYTOKEN" \
--header "Content-Type: application/json" \
--request POST \
--data '{"name":"My Timeseries","type":"timeseries"}' \
http://localhost:1324/api/objects
{
"id":"1a1f624e-96f9-416a-9982-6b1ef618661c",
"name":"My TS",
"description":"",
"owner":"myuser",
"app": "0519420b-e3cf-463f-b794-2adb440bfb9f",
"tags":"",
"type":"timeseries",
"meta":{"actor":false,"schema":{}},
"created_date":"2020-03-21",
"modified_date":null,
"owner_scope":"*",
"access":"*"
}
/api/objects/{objectid}
GET
Returns the object with the given IDURL Params
icon (boolean,false) - whether or not to include the object’s icon.
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c
{
"id":"1a1f624e-96f9-416a-9982-6b1ef618661c",
"name":"My TS",
"description":"",
"owner":"myuser",
"app": "0519420b-e3cf-463f-b794-2adb440bfb9f",
"tags":"",
"type":"timeseries",
"meta":{"actor":false,"schema":{}},
"created_date":"2020-03-21",
"modified_date":null,
"owner_scope":"*",
"access":"*"
}
PATCH
Updates the object with the included fields.The meta
object is updated on a per-field basis, meaning that
the object sent as the meta field will be merged with the existing meta values. Setting meta
to {"schema":{"type":"number"}}
in a timeseries object will update the schema
of the meta object, leaving all other fields intact. To delete a field from the meta object, set it to null ({"actor":null}
).
Body
name (string,null) - the object’s name
description (string,null) - the object’s description
icon (string,null) - object’s icon, base64 urlencoded
tags (string,null) - a set of space-separated tags to give the object
key (string,null) - a key to give the object for easy programmatic access (only objects belonging to apps can have keys)
owner_scope (string,null) - the set of space-separated scopes to give the object’s owner, if the object belongs to an app. “*” means all scopes.
meta (object,null) - the fields of object metadata to update. Each object type defines its own metadata.
Example
curl --header "Authorization: Bearer MYTOKEN" \
--header "Content-Type: application/json" \
--request PATCH \
--data '{"meta":{"schema":{"type":"number"}}}' \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c
{"result":"ok"}
DELETE
Deletes the given object, and all of its data.Example
curl --header "Authorization: Bearer MYTOKEN" \
--request DELETE \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c
{"result":"ok"}
Timeseries#
The timeseries is a builtin object type. It defines its own API for interacting with the datapoints contained in the series.
Meta#
Each object holds a meta
field. A timeseries object’s meta object has the following fields:
schema (object,{}) - a JSON Schema to which each datapoint must conform.
/api/objects/{objectid}/timeseries
GET
Returns the timeseries data subject to the given constraints.URL Params
t (float,string*,null) - get just the datapoint with the given timestamp
i (int,null) - get just the datapoint at the given index
t1 (float,string*,null) - return only datapoints where
t >= t1
t2 (float,string*,null) - return only datapoints where
t < t2
i1 (int,null) - return only datapoints where
index >= i1
i2 (int,null) - return only datapoints where
index < i2
limit (int,null) - return a maximum of this number of datapoints
transform (string,null) - a PipeScript transform to run on the data
*: The t
, t1
and t2
queries accept strings of times relative to now. For example, t1=now-2d
sets t1
to exactly 2 days ago.
Example
curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c/timeseries?t1=now-2h
[
{ "t": 1584812297, "d": 3 },
{ "t": 1584812303, "d": 2 },
{ "t": 1584812313, "d": 2 },
{ "t": 1584812339, "d": 2 }
]
POST
Insert new datapoints into the timeseriesURL Params
method (string,”update”) - the insert method, one of:
update - Overwrite any datapoints that already exist with time ranges defined by the inserted datapoints.
append - Only permit appending datapoints to the end of the timeseries
insert - Don’t permit inserting datapoints that interfere with data already in the timeseries
Body
A json array of datapoints, conforming to the timeseries schema, with each datapoint in the following format:{
// unix timestamp in seconds
"t": 1584812297.1,
// (optional) duration of the datapoint
"dt": 60.0,
// the datapoint's data (anything that can be encoded as json)
"d": 3
}
Example
curl --header "Authorization: Bearer MYTOKEN" \
--header "Content-Type: application/json" \
--request POST \
--data '[{"t":1584812297,"d":3},{"t":1584812303,"d":2}]' \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c/timeseries
{ "result": "ok" }
DELETE
Delete the timeseries data that satisfies the given constraintsURL Params
t (float,string*,null) - remove just the datapoint with the given timestamp
i (int,null) - remove just the datapoint at the given index
t1 (float,string*,null) - remove only datapoints where
t >= t1
t2 (float,string*,null) - remove only datapoints where
t < t2
i1 (int,null) - remove only datapoints where
index >= i1
i2 (int,null) - remove only datapoints where
index < i2
*: The t
, t1
and t2
queries accept strings of times relative to now. For example, t1=now-2d
sets t1
to exactly 2 days ago.
Example
curl --header "Authorization: Bearer MYTOKEN" \
--request DELETE \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c/timeseries?t1=now-2h
{ "result": "ok" }
/api/objects/{objectid}/timeseries/length
GET
Returns the number of datapoints in the timeseries.curl --header "Authorization: Bearer MYTOKEN" \
http://localhost:1324/api/objects/1a1f624e-96f9-416a-9982-6b1ef618661c/timeseries/length
4
Notifications#
Notifications are a built-in plugin that allows attaching messages to users/apps/objects. These messages are visible from the main heedy UI.
/api/notifications
GET
Read the list of notifications subject to the given constraints.URL Params
key (string,null) - only return the notifications with the given key
user (string,null) - limit to notifications for the given user
app (string,null) - limit to notifications for the given app
object (string,null) - limit to notifications for the given app
global (boolean,false) - limit to notifications that show in the notifications page
seen (boolean,null) - limit to notifications that have/have not been seen
dismissible (boolean,null) - limit to notifications that are/are not dismissible
type (string,null) - limit to notifications of the given type
include_self _(boolean,false) - whether to include self when
*
present. For example, whenuser=myuser&app=*
, notifications for user myuser are included if and only ifinclude_self
is true.
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
http://localhost:1324/api/notifications?user=myuser
POST
Create a notification for a user/app/object. If a notification with the given key exists for the given user/app/object, update the notification with the given data.
Body
key (string,required) - set the notification’s key (unique for the user/app/object’s notifications)
title (string,””) - the header text to show
description (string,””) - main notification content. Can include markdown.
user (string,required*) - add the notification to the given username
app (string,required*) - add the notification to the given app
object (string,required*) - add the notification to the given object
global (boolean,false) - show in the global notification page?
seen (boolean,false) - has the notification been seen by the user?
dismissible (boolean,true) - allow the user to dismiss the notifcation
type (string,null) - the notification type, one of
info,warning,error
actions (array,[]) - the list of actions to give the notification, which are shown to the user as buttons. Each action object has the following fields:
title (string,required) - the text to display in the button
href (string,required) - the url to navigate to. If it starts with
#
, it is relative to the UI. If starts with/
, relative to heedy’s root. Otherwise, it is considered a raw URL.description (string,””) - the tooltip to show on button hover
icon (string,””) - the icon to show in the button
new_window (boolean,false) - whether to open href in a new window
dismiss (boolean,false) - whether to dismiss the notification on click
*: Only one of the user/app/object fields can be set (the notification can only belong to a user or an app, or an object, not all at the same time)
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--header "Content-Type: application/json" \
--request POST \
--data '{"key":"mynotification","user":"myuser","title": "Hello World!"}' \
http://localhost:1324/api/notifications
{ "result": "ok" }
PATCH
Modify the included fields of all notifications that satisfy the constraints given in the URL Params.
URL Params
key (string,null) - only return the notifications with the given key
user (string,null) - limit to notifications for the given user
app (string,null) - limit to notifications for the given app
object (string,null) - limit to notifications for the given app
global (boolean,false) - limit to notifications that show in the notifications page
seen (boolean,null) - limit to notifications that have/have not been seen
dismissible (boolean,null) - limit to notifications that are/are not dismissible
type (string,null) - limit to notifications of the given type
include_self _(boolean,false) - whether to include self when
*
present. For example, whenuser=myuser&app=*
, notifications for user myuser are included if and only ifinclude_self
is true.
Body
key (string,null) - set the notification’s key (unique for the user/app/object’s notifications)
title (string,null) - the header text to show
description (string,null) - main notification content. Can include markdown.
global (boolean,null) - show in the global notification page?
seen (boolean,null) - has the notification been seen by the user?
dismissible (boolean,null) - allow the user to dismiss the notifcation
type (string,null) - the notification type, one of
info,warning,error
actions (array,null) - the list of actions to give the notification, which are shown to the user as buttons. Each action object has the following fields:
title (string,required) - the text to display in the button
href (string,required) - the url to navigate to. If it starts with
#
, it is relative to the UI. If starts with/
, relative to heedy’s root. Otherwise, it is considered a raw URL.description (string,””) - the tooltip to show on button hover
icon (string,””) - the icon to show in the button
new_window (boolean,false) - whether to open href in a new window
dismiss (boolean,false) - whether to dismiss the notification on click
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--header "Content-Type: application/json" \
--request PATCH \
--data '{"seen":true}' \
http://localhost:1324/api/notifications?user=myuser&key=mynotification
{ "result": "ok" }
DELETE
Deletes the notifications that satisfy the given constraints.
URL Params
key (string,null) - delete the notifications with the given key
user (string,null) - limit to notifications for the given user
app (string,null) - limit to notifications for the given app
object (string,null) - limit to notifications for the given app
global (boolean,false) - limit to notifications that show in the notifications page
seen (boolean,null) - limit to notifications that have/have not been seen
dismissible (boolean,null) - limit to notifications that are/are not dismissible
type (string,null) - limit to notifications of the given type
include_self _(boolean,false) - whether to include self when
*
present. For example, whenuser=myuser&app=*
, notifications for user myuser are included if and only ifinclude_self
is true.
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request DELETE \
http://localhost:1324/api/notifications?user=myuser&seen=true
{ "result": "ok" }
Key-Value Storage#
The key-value database is a built-in plugin, allowing other plugins to store metadata attached to users, apps and objects. It is recommended that a plugin use its own plugin name as the namespace under which it stores its data.
An app can also store its own metadata, by using its app ID or self
as the namespace when accessing the app’s key-value store.
/api/kv/users/{id}/{namespace}
GET
Returns a json object containing all of the key-value pairs in the given namespaceExample
curl --header "X-Heedy-Key: MYPLUGINKEY" \
http://localhost:1324/api/kv/users/myuser/myplugin
{
"mykey": 45.54
}
POST
Sets the key/values of the namespace to the posted body
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request POST \
--header "Content-Type: application/json" \
--data '{"mykey": 45.54}' \
http://localhost:1324/api/kv/users/myuser/myplugin
{ "result": "ok" }
PATCH
Updates only the given key/value pairs for the given namespace
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request PATCH \
--header "Content-Type: application/json" \
--data '{"mykey": 45.54}' \
http://localhost:1324/api/kv/users/myuser/myplugin
{ "result": "ok" }
/api/kv/users/{id}/{namespace}/{key}
GET
Get the value of the given key in the given namespace.Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
http://localhost:1324/api/kv/users/myuser/myplugin/mykey
45.54
POST
Sets the given key to the posted json value
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request POST \
--header "Content-Type: application/json" \
--data '45.54' \
http://localhost:1324/api/kv/users/myuser/myplugin/mykey
{ "result": "ok" }
DELETE
Deletes the given key from the given namespace.
Example
curl --header "X-Heedy-Key: MYPLUGINKEY" \
--request DELETE \
http://localhost:1324/api/kv/users/myuser/myplugin/mykey
{ "result": "ok" }
/api/kv/apps/{id}/{namespace}
Refer to /api/kv/users/{id}/{namespace}
, which has an identical API
/api/kv/apps/{id}/{namespace}/{key}
Refer to /api/kv/users/{id}/{namespace}/{key}
, which has an identical API
/api/kv/objects/{id}/{namespace}
Refer to /api/kv/users/{id}/{namespace}
, which has an identical API
/api/kv/objects/{id}/{namespace}/{key}
Refer to /api/kv/users/{id}/{namespace}/{key}
, which has an identical API