Note: This guide is intended for developers that want to take advantage of the HealthBox API. If you're a HealthBox user, consider checking out the USAGE.md document for information on how to set up HealthBox. However, you may still be interested in reading it to better understand how applications interface with your data.
The HealthBox API provides a method for developers of both devices that track health metric data and apps that need access to health metric data submit and retrieve the involved metric data. The API, which is based on an HTTP server, is designed to be minimalist and easy to implement.
Authentication is based on the concept of an API key, which is created by the owner of the HealthBox server. API keys are configurable by the owner to allow read and/or write access on a metric by metric basis. For your program to communicate with HealthBox, it will need an API key, which can be generated by the user. See below to learn how the API key system works.
There are two types of applications that can interact with the HealthBox API: sources and apps. A source is an application that generates and submits health metric data to the API. An app is an application that retrieves health metric data from the API. API keys are designated by the owner to only work for either sources or apps. Most API methods are available to only sources or apps, and if a method is called with a key designated for the wrong type of application, an error is thrown. (Error formatting is described in-depth below.)
- source: A piece of software or hardware that submits data to HealthBox. API keys of this type have write permissions only.
- app: A piece of software or hardware that receives data from HealthBox. API keys of this type have read permission only.
Please note that because sources can only submit data and apps can only read it, your program or device may need two separate API keys if it needs to do both actions.
HealthBox uses a simple HTTP/HTTPS system for interfacing with devices and programs. To interface with HealthBox, your device or program should use this general structure. However, keep in mind that this structure can differ slightly, especially depending on whether you want to retrieve data (app) or submit it (source).
http://host
:port
/api/caller_type
/endpoint
?api_key=api_key
&submission=submission
In order to communicate with HealthBox, simply form a URL using the structure above, replacing each variable based on the information in the 'Variable Definitions' section below. Then submit the request using a library in your programming language of choice.
Applications that identify with the "source"
caller type have access to only one method, "submit"
. "submit"
is used to submit a sample of data to a specific metric. The data consists of a JSON dictionary, which should be URL-encoded and passed as the optional submission
variable in the URL described in the 'Calling A Method' section of this documentation. The dictionary should have only two items, "timestamp"
and "data"
. "timestamp"
should be a Unix timestamp of when the user of your app or device submitted the data. "data"
should consist of data about the metric, composed according to the specifications described in METRICS.md
and metrics.py
.
Here's an example of a submission
variable before being URL-encoded and with optional spacing added, assuming the metric has an ID of "A1"
, or "Steps" in the "Activity" category:
{
"timestamp": 1577966400,
"data": {
"steps_count": 100,
"start_time": 1577836800,
"end_time": 1577923199
}
}
Before URL-encoding, the variable should be converted to JSON, with extra spacing removed, so it looks like this:
{"timestamp": 1577966400,, "data": {"steps_count": 100, "start_time": 1577836800,, "end_time": 1577923199}}
After URL-encoding, the variable might look like this:
%7B%22timestamp%22%3A%203133944530000%2C%20%22data%22%3A%20%7B%22steps_count%22%3A%20100%2C%20%22start_time%22%3A%201596133702965%2C%20%22end_time%22%3A%201596133705965%7D%7D
It can then be inserted into the URL after &submission=
. If there is no submission data, &submission=
should be omitted from the URL completely.
Applications that identify with the "app"
caller type have access to two methods, "current"
and "past"
. "current"
returns the most recent sample for the given metric ID, if there is one, and "past"
returns a list of all samples for the given metric ID. These methods do not need any additional variables. (See Return values for more information on how to parse these return values.)
host
is a string indicating the IP or domain name associated with the HealthBox server. This should be specified by the user of your application, with a default value of"localhost"
.port
is a number indicating the port associated with the HealthBox server. This should be specified by the user of your application, with a default value of5050
.caller_type
is a string, either"source"
or"app"
, indicating the type of application that's calling the API method.endpoint
is a string that's composed of multiple elements joined with a slash ('/'
). The endpoint should have the following elements: the type of resource being accessed, an ID identifying the resource, and the method that defines what action to take on the resource. See below to learn how to compose these three elements.api_key
is a string indicating the API key provided to your application by the owner. If the API key passed is not valid for the given request, an error will be returned. (See Return values for more information.) Althoughapi_key
should theoretically be URI-encoded, API keys generated by the official HealthBox server consist of 16-character-long hexadecimal strings that do not contain any special characters, so URI-encoding ofapi_key
is not a necessity.submission
is a string containing a JSON dictionary with a sample. This variable, and its associated"&submission="
prefix, are only necessary if the caller type is"source"
and the method is"submit"
. (See Methods available to sources for more information.)
Currently, there is only one type of resource, "metrics"
. This should remain this way for the foreseeable future, but may change down the road.
Health metrics in HealthBox are split into 4 categories for sake of organization.
- Activity
- Mental Health
- Nutrition
- Measurements
A Metric ID
is a 2 character identification key that a uniquely identifies a specific metric. A Metric ID may look like B3
, or A6
.
All metrics and their IDs are listed in metrics.py
. For example, the metric ID for "Steps", which is part of the "Activity" category, is "A1"
, because the ID of the "Activity" category is specified as "A", and "Steps" is the first metric in the "Activity" category's list of metrics.
All API endpoints will return a JSON dictionary with at least two fields, "success"
and "error"
. If the API call was successful, "success"
will contain true
and "error"
will contain null
; otherwise, "success"
will contain false
and "error"
will contain a string explaining what went wrong. A full list of values for "error"
can be found by reading web_server.py
, specifically the api
method on the HealthBoxWebServerRoutes
object.
Additionally, if the API call was successful, extra fields may be added to the JSON dictionary according to the method. The "submit"
method will return no extra fields, the "current"
method will return one extra field, "current"
, which will contain a dictionary with the most recent sample, and the "past"
method will return one extra field, "past"
, which will contain a list of dictionaries, where each dictionary is a sample, sorted with the oldest samples first. (If no samples are available, "current"
will return an error, whereas "past"
will return an empty list in the "past"
field.)
If something internally went wrong, the connection is immediately closed and the error is logged to the HealthBox terminal. At this point, you should instruct your user to examine the HealthBox console and report the error using this GitHub repository. Even if the error is caused by a malformed request, report the error anyway -- malformed requests are supposed to be handled with an error response, not by causing an internal error and closing the connection, so if that has happened, you've found an edge case that we'd like to patch.
For sake of organization, ease of use, and continuity, you are encouraged to use the "Works with HealthBox" icon to indicate a program that uses HealthBox. While this isn't necessary, it helps users to quickly determine whether an application will work with HealthBox. The icon should be placed somewhere prominent, but out of the way on the program's homepage. You can find the Works With HealthBox image in the "assets" folder.
If you do create an open source tool that uses HealthBox, and want to promote it, get in touch with the HealthBox developers, and we'll add your project to a list of programs HealthBox users can try out.
The developers of HealthBox have written an example program that allows a simple way to interact with the HealthBox API, either with code or via the terminal. This program is written in Python and is named api_tester.py
. The ExampleAPIConsumer
class is intended to be imported and used to interact with the API via code, and the ExampleAPIConsumerTerminalWrapper
class uses the ExampleAPIConsumer
class to provide a simple terminal user interface usable to interact with the API by typing the values of variables into the terminal. (Little to no checks are performed on the syntax of these variables. Any errors returned by the API are printed by the terminal interface.)
The program uses the requests
library for the majority of its functionality. It also uses several functions provided by utils.py
in the HealthBox repository. As such, it's not intended to provide a portable solution, but rather a reference implementation for your own usage of the API. Even so, if you find a defect with the API tester, feel free to report it using this GitHub repository.
If you plan to use HealthBox maliciously, here's a forewarning: a system is in place to log the IP and port of the application, as well as all information about the API request, when a request is made, whether or not it's successful. This log is available to the owner through the HealthBox terminal interface, which also provides a way to temporarily disable API keys, so the owner can block badly behaving applications. If this happens, you will be returned a separate error -- read web_server.py
for more information -- and can ask the owner to re-enable your API key once your application's behavior has been fixed.
Again, if you find a defect in HealthBox's API or database security system, please report it to the developers using this GitHub repository's issue system. We also accept improvements and suggestions, so if you think our code is lacking in some way, feel free to let us know. Thanks for using HealthBox, and happy coding!