## Endpoint Path/Prefix

All Reactor HTTP API endpoints are accessible at the service IP and port beneath the `/api/v1/` prefix path of the host system. For example, the `alive` endpoint of a typical Reactor system running on host address 192.168.0.10 would be at the URL `http://192.168.0.10:8111/api/v1/alive`.

## Documentation Conventions

Within the endpoint paths shown in this documentation, named path parameters are indicated by a `:` (colon) followed by the name; for example, `capability/:id` means that a capability ID/name is expected to follow the slash after `capability` in the final URL. For example, fetching the definition of the `power_switch` capability would be done with the full URL `http://host-ip:8111/api/v1/capability/power_switch`. Note that the `:` is not part of the final endpoint URL.

## API Conventions

### Character Set

All charset encoding is UTF-8.

### HTTP Request Methods

This RESTful API attempts to follow RFC2616, which regards the PUT method as preferred where the action is idempotent, and the POST method preferable otherwise. The GET method is used for data queries and simple actions. The DELETE method is used for removing data. Each endpoint's documentation describes which methods it supports.

### Request Body

For endpoints accessible via POST or PUT, data in the request body may be specified as JSON or form data. JSON is recommended in all cases, however, form data format may be easier for requests where the body data is only simple key/value pairs. Below, the ubiquitous `curl` command is used to illustrate how properly-formed requests with body data may be constructed, but this is by no means the only way.

To send JSON data, make sure the `Content-Type` request header is given with the value `application/json`. Employing `curl`, there are two ways to structure the command line. The "classic" form uses explicit options to set the request method (`-X`), header value (`-H`), and body content (`-d`):

        curl -X POST -H 'content-type: application/json' \
             -d '{"profile": "default", "message": "Greetings!"}' \
             'http://host-ip:8111/api/v1/notify/SMTP'

More recent "modern" versions of `curl` support a shortcut option:

        # Modern curl... POST is default method with --json; add -X PUT if needed
        curl --json '{"message": "Greetings!"}' 'http://host-ip:8111/api/v1/notify/SMTP'

To send form-data bodies, the `Content-Type` header is given with the value `application/x-www-form-urlencoded`. The request body then contains URL-encoded `key=value` pairs joined by ampersands (`&`). Below are examples with the "classic" and "modern" `curl` command line options:

        # Classic curl
        curl -X POST -H 'content-type: application/x-www-form-urlencoded' \
             -d 'profile=default&message=Greetings%21' \
             'http://host-ip:8111/api/v1/notify/SMTP'

        # Modern curl
        curl --data-urlencode "message=Greetings!" 'http://host-ip:8111/api/v1/notify/SMTP'

In the case of "modern" `curl`, the data does not need to be URL-encoded on the command line; `curl` will do it for you. However, because of this automatic encoding, you may not use `=`, `&`, or `@` characters as part of a key or value (for example, `message=I=am=Groot` is invalid). Refer to your system's `curl` documentation for details and alternatives, or use the classic options and URL-encode the values yourself.

### Responses

Except where indicated, all endpoints return a JSON structure (regardless of any `Accept` request header value). Generally, data-requesting endpoints return their data unwrapped. That is, there is no surrounding structure giving the status of the request in addition to the requested data. HTTP errors (400, 404, etc.) are returned in preference to giving a valid HTTP reply containing an error structure. Example (valid data response):

    {
        "time": 1636055110371,
        "timezone": "America/New_York",
        "tzoffset": -240,
        "engine_time": 1636055110372
    }

In the few endpoints where data is not returned, the standard non-data response format is a JSON object with a `status` field containing a boolean value; additional fields may be provided and are endpoint-dependent. Examples (valid and error):

    { "status": true }
    { "status": false, "message": "The requested object was not found" }

Tip: Most Linux distributions support the `jq` utility, which is very handy for parsing and navigating the JSON response from Reactor more easily than trying to pick it apart with text tools like `grep`, `awk` and `sed`.

### Date/Time Data Handling

Since most data reported by Reactor or received into it is JSON form, and JSON does not have date or time as standard data types, almost all dates/times in Reactor will be 64-bit integer timestamps in milliseconds since the Unix Epoch (i.e. JavaScript timestamps). However, there are exceptions: Reactor Controllers may receive dates/times as strings (e.g. ISO 8601), integer seconds, etc., from remote APIs and will often store them as received on an attribute of an extended capability (identified by the `x_` prefix), since it is sometimes useful to have the source value exactly as presented. However, timestamps on attributes defined in Reactor-native capabilities will always use millisecond integer timestamps.

## Troubleshooting HTTP API Requests

It is better to use `curl` or a similar Linux tool from the command line to form and debug HTTP request URLs than it is to use a browser. You can use a browser to try a request, but if you are getting an error or unexpected result, switching to `curl` will provide more information — browsers tend to "water down" the details of HTTP errors.

Here are some general steps to take when troubleshooting:

1. First, always verify connectivity. The simplest request is the `alive` request (`http://ip:8111/api/v1/alive`). If Reactor is up and running, this will always produce a result with no parameters. If you can't complete this test, either Reactor is not running, or the IP or port you are trying to access isn't available in the configuration.
2. If you are getting a 401 or 403 error code, then access control has been enabled in your Reactor configuration. Make sure your ACLs (access control lists) are configured to allow the endpoint you are attempting to reach from the host making the query, and that you are using one of the required authentication mechanisms configured by the ACL(s). See Access Control.
3. If you get an error code 404 with a Not Found message, that means either you have entered the IP URL incorrectly, or the object you are trying to access (rule, reaction, etc.) cannot be found.
4. If you are getting a 400 or 500 error code, possibly with a Request failed message, check the Reactor log file. Find the lines with `httpapi` identified as the subsystem. The error here will often be sufficient to help you correct your URL or parameters. You may need to look above and below the matching lines to see the full context of the message.
5. Make sure you are using the correct HTTP method. Not all endpoints support simple `GET` method access; some require `POST` or `PUT`.
6. If you are sending body data with a `POST` or `PUT` method request, make sure you specify the `Content-Type` header correctly in the request headers. To send JSON data, you must be using the `application/json` content type. For an example of this, see the `variable/:name/set` endpoint.
7. Try a simpler request for the object. For example, if you are trying to do a `perform` request to run an action on an entity, but getting an error, try running just the query for the entity and make sure it can return a correct result: `http://ip:8111/api/v1/entity/id`
8. If you need to post on the SmartHome Community for help, remember to follow the posting guidelines -- show your work, give all the details up front. The more effort you put in to asking your question, the more likely someone will put in the effort to help and the quicker they can answer without a lot of back and forth.

Updated 2026-Jun-22