Integration APIs

In Indigo v2022.2, we’ve completely redesigned the Indigo Web Server plugin (commonly referred to as IWS). The first major change is the new Indigo Touch for Web UI. We know you'll love this new UI (particularly given the old UI which was super dated):

This article, however, is about the two new APIs in IWS that developers can use to integrate Indigo with external services:

  • WebSocket API – (which the new Indigo Touch Web UI uses, and
  • HTTP API – shares as much of the messaging construction with the WebSocket interface as is practical.

Both of these APIs are authenticated with HTTP Digest and API Keys (either as a query string or preferably an Authorization header) depending on how the user configures it in the Start Local Server dialog.

NOTE:

  • We’re deprecating HTTP Basic authentication due to its insecure nature.
  • The old REST API has been deprecated in favor of the new HTTP API.

Versioning

A quick note on versioning: moving forward, all APIs will be versioned under the following scheme:

  • /v2/ - this is the top level version number and will change as necessary

Python vs JavaScript

In these APIs, we’re using JSON (JavaScript Object Notation) as the message format for communicating between the WebSocket and HTTP APIs and IWS. In JavaScript, an “object” definition looks (almost) exactly like a Python dictionary (and vice versa). So we may refer to an object or dictionary (dict): for the purposes of this document, they refer to the same JSON construct. For example, we may call this an object or a dict:

{
  "key1": "value 1",
  "key2": 2
}

We expect there will be both Python and JavaScript users integrating our APIs, so we wanted to explicitly call this out. As a primarily Python organization, you may notice a bias towards “dict”.

Python developers will notice the use of null in the message descriptions. This corresponds to the Python None object. Also of note are the booleans true and false, which are capitalized in Python but not in JSON. Here’s a handy cheat sheet:

PythonJSON Equivalent
True true
False false
float Number
int Number
None null
dict Object
list Array
tuple Array
str String

If you are new to JSON, you may want to use the JSON Validator website to validate that the JSON message you are sending is valid JSON.

WebSocket API

The Indigo WebSocket API is a persistent connection, meaning that your app/integration will open the connection and keep it open until your app/integration quits. If you are looking for a transactional API, try our HTTP API. WebSockets are bidirectional TCP connections, which clients can read from and write to – much like you can a socket or serial connection. This initial version of this API is meant to support functionality like that provided by the Indigo Touch and Domotics Pat clients and does not provide all the necessary bits to support a full configuration clients like the Mac Client. In other words, there are things that the Indigo client can do that are not supported in the WebSockets API at this time.

There are 5 WebSocket feeds that that are available in this release:

  • /v2/api/ws/device-feed - WebSocket to do all communication about devices
  • /v2/api/ws/variable-feed - WebSocket to do all communication about variables
  • /v2/api/ws/action-feed - WebSocket to do all communication about action groups
  • /v2/api/ws/page-feed - WebSocket to do all communication about control pages
  • /v2/api/ws/log-feed - WebSocket to do all communication about logs

Each feed (except log feed) sends the following server messages:

  • add (when a new Indigo object is added)
  • patch (when an Indigo object changes - you would apply the patch to an existing object)
  • delete (when the Indigo object is deleted)
  • refresh (when you request a fresh copy of a device or the entire list of devices)

WebSocket Lifecycle

The flow of how you will interact with any of the WebSockets above will generally be:

  1. Setup:
    • Open the websocket connection, and
    • Send a refresh message to obtain all of the existing instances of that Indigo type in your database.
  2. Routine operation (asynchronously processing for the lifetime of your app/integration):
    • Read incoming messages from the server (add/patch/delete/refresh) and handle those as appropriate, and
    • Write messages to the server to instruct the server to do something (commands like statusRequest, turnOn, or refresh).
  3. Close the connection when your app/integration quits.

The log-feed is different in that it will only send add messages with the appropriate log event object defined below.

Authentication

WebSocket API requests must be authenticated using an API Key. You can manage API Keys in the Authorizations section of your Indigo Account. Using keys instead of your Indigo Server username/password has several advantages: you can, at any time, revoke an API key, and it will immediately cause anything using it to fail. This will not affect anything else using a your username/password or another API key, so your server protections against intrusions are much more granular. Also, if someone does manage to get your API Key, they can control devices, but they cannot modify your database (add/delete devices, etc) - that is reserved for Indigo clients using the username/password.

The best way to use an API Key is to include it in an Authorization header on your HTTP request. If you are using a system which does not allow you to set headers for your HTTP request, you can include the API Key as a query argument with the URL:

wss://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/ws/device-feed?api-key=YOUR-API-KEY

Note the protocol: wss. WebSockets actually begin their life as HTTP/HTTPS connections, which the WebSocket client then requests the server to upgrade to a WebSocket. In this respect, you can think of WSS as HTTPS (protected) and WS as HTTP (unprotected). When using WSS, such as when you are using your Indigo Reflector, then your API Key (in both instances) is protected by the TLS security used by the HTTPS protocol. You may use the API locally (or thorough your own router port forwarding), but those connections will be WS and will not be secure. It is highly recommended that you always use your Indigo Reflector because it provides a very simple and secure solution for accessing your system. IMPORTANT! Be sure not to share your API keys with anyone not authorized to use them — especially in posts to the Indigo user forums.

Examples

The WebSocket and HTTP APIs are designed to be familiar to those that have been using the legacy RESTful API. However, anyone with knowledge of Python, JavaScript or similar languages should be able to pick up the structure of the new APIs very quickly. To help those making the transition as well as those learning to use API calls for the first time, we've laid out several examples to show how API calls are made, as well as all the current API hooks available.

Here's a simple Python script to open the device-feed and print out any messages it receives (you'll need to pip3 install websockets before running it).

Python Receiver Example

This example opens a websocket connection and prints all messages received to the console. It runs until you stop it.

import asyncio
import websockets
import json
 
API_KEY = 'YOUR-API-KEY'
 
async def receiver():
    try:
        headers = {"Authorization": f"Bearer {API_KEY}"}
        async with websockets.connect("ws://localhost:8176/v2/api/ws/device-feed", extra_headers=headers) as websocket:
            while True:
                message = await websocket.recv()
                print(json.dumps(json.loads(message), indent=2))
    except Exception as exc:
        print(f"Exception:\n{exc}")
 
asyncio.run(receiver())

Python Receiver/Sender Example

This example opens a websocket connection and shows how messages can be received and sent from the same websocket connection. It runs until the loop counters run out.

import asyncio
import json
from websockets import connect
 
API_KEY = 'YOUR_API_KEY'  # YOUR API KEY HERE
DEVICE_ID = 12345678  # YOUR DEVICE ID HERE
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
URI = "ws://127.0.0.1:8176/v2/api/ws/device-feed"  # wss:// if using the reflector
 
async def receiver(ws):
    try:
        print("Starting receiver task")
        # Ask for a refresh of device with ID 12345678
        refresh_message = {
            "id": "initial-device-refresh",
            "message": "refresh",
            "objectType": "indigo.Device",
            "objectId": DEVICE_ID
        }
        await ws.send(json.dumps(refresh_message))
        counter = 0
        device = {}
 
        while counter < 20:
            # just keep looping waiting for a message to come
            log_string = "ignoring message"
            message_json = await ws.recv()
            message = json.loads(message_json)
            message_type = message['message']
 
            if message_type == "refresh":
                # This is the response to the refresh message we sent above. It gets us a full copy of the device.
                device = message["objectDict"]
                log_string = f"receiver: device refresh message: '{device.get('name', 'unknown')}'"
 
            elif message_type == "patch":
                # There's been a change, so confirm it's the device we want then log the change
                if message["objectId"] == device["id"]:
                    log_string = f"'receiver: device patch message: {device.get('name', 'unknown')}' update: \n{message_json}"
 
            print(f"receiver: loop count: {counter}")
            print(f"receiver: {log_string}")
            counter += 1
 
    except Exception as exc:
        print(f"Exception:\n{exc}")
 
async def sender(ws, count):
    try:
        print("Starting sender task")
        message = {
            "id": "initial-device-refresh",
            "message": "refresh",
            "objectType": "indigo.Device",
            "objectId": DEVICE_ID
        }
 
        for count in range(10):
            print(f"sender: loop count: {count}")
            msg = json.dumps(message)
            print(f"sender: sending message: {msg}")
            await ws.send(json.dumps(msg))
            await asyncio.sleep(5)
 
    except Exception as exc:
        print(f"Exception:\n{exc}")
 
async def main():
    try:
        async with connect(URI, extra_headers=HEADERS) as websocket:
            await asyncio.gather(receiver(websocket), sender(websocket, 10))
 
    except Exception as exc:
        print(f"Exception:\n{exc}")
 
asyncio.run(main())

JavaScript Example

Here's a simple nodejs JavaScript to open the device-feed and print out any messages it receives (you'll need to npm install websocket before running it).

const APIKEY = "YOUR-API-KEY";
 
const W3CWebSocket = require("websocket").w3cwebsocket;
 
console.log("Creating websocket");
 
const client = new W3CWebSocket(
  `ws://localhost:8176/v2/api/ws/device-feed?api-key=${APIKEY}`
);
client.onmessage = function (message) {
  console.log(message.data);
};
client.onerror = function (err) {
  console.log(`Error: ${JSON.stringify(err)}`);
};

Device Feed

This is the WebSocket you'll use for all device-related communication. You will receive the following messages from the Indigo server during the lifetime of the WebSocket.

Here are the URLs you will use to connect to this feed.

ws://localhost:8176/v2/api/ws/device-feed

wss://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/ws/device-feed

Device messages from the server

The following are examples of all the device messages that you will receive from the server.

add device message
{
  "message": "add",
  "objectType": "indigo.Device",
  objectDict": {
    "class": "indigo.DimmerDevice",
    "address": "3B.04.7A",
    "batteryLevel": null,
    "blueLevel": null,
    "brightness": 100,
    "buttonConfiguredCount": 0,
    "buttonGroupCount": 1,
    "configured": true,
    "defaultBrightness": 100,
    "description": "- sample device -",
    "deviceTypeId": "",
    "displayStateId": "brightnessLevel",
    "displayStateImageSel": "indigo.kStateImageSel.DimmerOn",
    "displayStateValRaw": 100,
    "displayStateValUi": "100",
    "enabled": true,
    "energyAccumBaseTime": null,
    "energyAccumTimeDelta": null,
    "energyAccumTotal": null,
    "energyCurLevel": null,
    "errorState": "",
    "folderId": 1552926800,
    "globalProps": {
      "com.indigodomo.indigoserver": {},
      "emptyDict": {}
    },
    "greenLevel": null,
    "id": 1508839119,
    "lastChanged": "2023-02-16T15:43:53",
    "lastSuccessfulComm": "2023-02-16T15:43:53",
    "ledStates": [],
    "model": "LampLinc (dual-band)",
    "name": "Insteon Dimmer",
    "onBrightensToDefaultToggle": true,
    "onBrightensToLast": false,
    "onState": true,
    "ownerProps": {},
    "pluginId": "",
    "pluginProps": {},
    "protocol": "indigo.kProtocol.Insteon",
    "redLevel": null,
    "remoteDisplay": false,
    "sharedProps": {},
    "states": {
      "brightnessLevel": 100,
      "onOffState": true
    },
    "subModel": "Plug-In",
    "subType": "Plug-In",
    "supportsAllLightsOnOff": true,
    "supportsAllOff": true,
    "supportsColor": false,
    "supportsOnState": true,
    "supportsRGB": false,
    "supportsRGBandWhiteSimultaneously": false,
    "supportsStatusRequest": true,
    "supportsTwoWhiteLevels": false,
    "supportsTwoWhiteLevelsSimultaneously": false,
    "supportsWhite": false,
    "supportsWhiteTemperature": false,
    "version": 67,
    "whiteLevel": null,
    "whiteLevel2": null,
    "whiteTemperature": null
  }
}

When a new device is added to the Indigo Server after you've opened the connection, you will receive this message. It contains a device object that you will want to add to your device list (since you'll want to patch it as it changes over time - see the next section). You'll also receive this message when a device's remote display property is changed from False to True.

update device message
{
  "message": "patch",
  "objectType": "indigo.Device",
  "objectId": 1508839119,
  "patch": [
    [
      "change",
      "brightness",
      [100, 0]
    ],
    [
      "change",
      "displayStateImageSel",
      ["indigo.kStateImageSel.DimmerOn", "indigo.kStateImageSel.DimmerOff"]
    ],
    [
      "change",
      "displayStateValRaw",
      [100,  0]
    ],
    [
      "change",
      "displayStateValUi",
      ["100", "0"]
    ],
    [
      "change",
      "lastChanged",
      ["2023-02-17T16:29:56", "2023-02-17T16:30:54"]
    ],
    [
      "change",
      "lastSuccessfulComm",
      ["2023-02-17T16:29:56", "2023-02-17T16:30:54"]
    ],
    [
      "change",
      "onState",
      [true, false]
    ],
    [
      "change",
      "states.brightnessLevel",
      [100, 0]
    ],
    [
      "change",
      "states.onOffState",
      [true, false]
    ]
  ]
}

Patch objects are created via the dictdiffer python module, by comparing the device dictionary (dict(some_device)) for the old device with the one for the new dictionary as they are received in the device_updated() plugin method call. We've implemented a JavaScript library, dictdiffer-js, to patch JavaScript objects given the patch object created by the dictdiffer Python library. You can use it in your projects if you like.

device refresh messages

When you send a command that asks to refresh the entire list of devices, you'll receive the following message from the server:

{
  "id": "optional-user-generated-refresh-device-list-message", // Reserved for future use.
  "message": "refresh",
  "objectType": "indigo.Device",
  "list": []
}

And if you requested just a single device refresh, you will receive the following message from the server:

{
  "id": "optional-user-generated-refresh-device-message",
  "message": "refresh",
  "objectType": "indigo.Device",
  "objectDict": {}
}

Note that the first message includes a list of objectDict elements, and the second includes a single objectDict element.

delete device message
{
  "message": "delete",
  "objectType": "indigo.Device",
  "objectId": 123456789
}

This is the simplest of the messages, as it just contains the Indigo ID of the device to delete from your collection. You'll receive this message when a device is deleted from the Indigo server and when a device's remote display property is set from True to False.

Device messages to the server

You have a variety of messages you can send to the server.

device refresh requests

To refresh either the full device list or a single device from the server, send the following message.

{
  "id": "optional-user-generated-refresh-device-message",
  "message": "refresh",
  // Specify the object type
  "objectType": "indigo.Device",
  "objectId": 123456789
}

If you want the entire device list, simply omit the objectId key and the server will return the full list. The server will respond with the appropriate device refresh message shown above.

device command messages

To command devices to do something, you will be using the Device Command Messages described below. For instance, to toggle a lamp device, you would send the following message:

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.toggle",
  "objectId": 123456789,
}

You will receive a “patch” message as a result of this command.

Variable Feed

This is the WebSocket you'll use for all variable-related communication. You will receive the following messages from the Indigo server during the lifetime of the WebSocket.

Here are the URLs you will use to connect to this feed.

ws://localhost:8176/v2/api/ws/variable-feed

wss://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/ws/variable-feed

Variable messages from the server

The following is an example of the variable message that you will receive from the server.

Example variable object (dictionary in Python)
{
  "class": "indigo.Variable",
  "description": "",
  "folderId": 0,
  "globalProps": {
    "com.indigodomo.indigoserver": {}
  },
  "id": 345633244,
  "name": "house_status",
  "pluginProps": {},
  "readOnly": false,
  "remoteDisplay": true,
  "sharedProps": {},
  "value": "home"
}

Here are some examples of the server messages that clients will receive on the variable feed.

add variable message
{
  "message": "add",
  "objectType": "indigo.Variable",
  "objectDict": {} // Variable object as outlined above
}

When a new variable is added to the Indigo Server after you've opened the connection, you will receive this message. It contains a variable object that you will want to add to your variable list (since you'll want to patch it as it changes over time - see the next section). You'll also receive this message when a variable's remote display property is changed from False to True.

update variable message
{
  "message": "patch", // we use a patch rather than send the entire updated device
  "objectType": "indigo.Variable",
  "patch": {}  // A patch object - see the Object Patches below for details
}

Variable patch objects are created via the dictdiffer python module by comparing the variable dictionary (dict(some_variable)) for the old variable with the one for the new dictionary as they are received in the variable_updated() Plugin method call.

delete variable message
{
  "message": "delete",
  "objectType": "indigo.Variable",
  "objectId": 123456789
}

This is the simplest of the messages, as it just contains the Indigo ID of the variable to delete from your collection. You'll receive this message when a variable is deleted from the Indigo server and when a variable's remote display property is set from True to False.

Variable messages to the server

There are a few messages you can send to the server.

variable refresh messages
{
  "id": "optional-user-generated-id", // Reserved for future use.
  "message": "refresh",
  "objectType": "indigo.Variable",
  "objectDict": {} // Variable object as outlined above
}
Example refresh all variables message
{
  "id": "optional-user-generated-id", // Reserved for future use.
  "message": "refresh",
  "objectType": "indigo.Variable",
  "list": [] // a list of Variable objects as outlined above
}

variable command messages

The updateValue command is currently the only command message you can send to the variable feed. It closely mirrors the Python-based IOM command for updating variables. This was completely intentional to make learning one API a stepping stone to another. The HTTP API messages and the Websocket API messages are identical, and are very clearly a JSON-rendered version of the associated IOM command.

updateValue
{
  // Note, values passed in the parameter dictionary must be strings. You can
  // pass in an empty string ("") to clear the variable value.
  "id": "optional-user-generated-id", // Reserved for future use.
  "message": "indigo.variable.updateValue",
  "objectId": 123456789,  // the variable id to update
  "parameters": {
    "value": "Some string value"
  }
}

Action Group Feed

This is the WebSocket you'll use for all action group-related communication. You will receive the following messages from the Indigo server during the lifetime of the WebSocket.

Here are the URLs you will use to connect to this feed.

ws://localhost:8176/v2/api/ws/action-feed

wss://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/ws/action-feed

Action Group messages from the server

The following are examples of all the action group messages that you will receive from the server.

Example action group object (dictionary in Python)
{
  "class": "indigo.ActionGroup",
  "description": "",
  "folderId": 532526508,
  "globalProps": {
    "com.indigodomo.indigoserver": {
      "speakDelayTime": "5",
      "speakTextVariable": "speech_string"
    }
  },
  "id": 94914463,
  "name": "Movie Night",
  "pluginProps": {},
  "remoteDisplay": true,
  "sharedProps": {
    "speakDelayTime": "5",
    "speakTextVariable": "speech_string"
  }
}

Here are some examples of the server messages that clients will receive on the action feed.

add action group message
{
  "message": "add",
  "objectType": "indigo.ActionGroup",
  "objectDict": {} // ActionGroup object as outlined above
}

When a new action group is added to the Indigo Server after you've opened the connection, you will receive this message. It contains an action group object object that you will want to add to your action group list (since you'll want to patch it as it changes over time - see the next section). You'll also receive this message when an action group's remote display property is changed from False to True.

update action group message

The update action group message is received when an action group has been updated on the Indigo server. It doesn't allow users to update action groups via the WebSocket API.

{
  "message": "patch", // we use a patch rather than send the entire updated device
  "objectType": "indigo.ActionGroup",
  "patch": {}  // A patch object - see the Object Patches below for details
}

Action group patch objects are created via the dictdiffer python module, by comparing the action dictionary (dict(some_action_group)) for the old action with the one for the new dictionary as they are received in the action_group_updated() Plugin method call.

delete action group message
{
  "message": "delete",
  "objectType": "indigo.ActionGroup",
  "objectId": 123456789
}

This is the simplest of the messages, as it just contains the Indigo ID of the action group to delete from your collection. You'll receive this message when an action group is deleted from the Indigo server and when a action group's remote display property is set from True to False.

Action Group messages to the server

The following are examples of the action group messages that you can send to the server.

action group refresh messages
{
  "id": "optional-user-generated-id", // Reserved for future use.
  "message": "refresh",
  "objectType": "indigo.ActionGroup",
  "objectDict": {} // ActionGroup object as outlined above
}
Example refresh all action groups message
{
  "id": "optional-user-generated-id", // Reserved for future use.
  "message": "refresh",
  "objectType": "indigo.ActionGroup",
  "list": [] // a list of ActionGroup objects as outlined above
}

action group command messages

The execute command is currently the only command message you can send to the action group feed. It closely mirrors the Python-based IOM command for executing action groups. This was completely intentional to make learning one API a stepping stone to another. The HTTP API messages and the Websocket API messages are identical, and are very clearly a JSON-rendered version of the associated IOM command.

Execute
{
  "id": "optional-user-generated-id", // Reserved for future use.
  "message": "indigo.actionGroup.execute",
  "objectId": 123456789  // the action group id to execute
}

Control Page Feed

This is the WebSocket you'll use for all control page-related communication. You will receive the following messages from the Indigo server during the lifetime of the WebSocket. The control page feed has no command messages you can send to the server; rather, it's purpose is to use incoming messages to manage a list of the available control pages which (presumably) the user would select to open that page.

Here are the URLs you will use to connect to this feed.

ws://localhost:8176/v2/api/ws/page-feed

wss://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/ws/page-feed

Control Page messages from the server

The following are examples of the control page messages that you will receive from the server.

Example variable object (dictionary in Python)
{
  "class": "indigo.ControlPage",
  "backgroundImage": "",
  "description": "",
  "folderId": 0,
  "globalProps": {},
  "hideTabBar": true,
  "id": 963336187,
  "name": "Weather Images",
  "pluginProps": {},
  "remoteDisplay": true,
  "sharedProps": {}
}

Here are some examples of the server messages that clients will receive on the variable feed.

add control page message
{
  "message": "add",
  "objectType": "indigo.ControlPage",
  "objectDict": {} // ControlPage object as outlined above
}

When a new control page is added to the Indigo Server after you've opened the connection, you will receive this message. It contains a control page that you will want to add to your control page list (since you'll want to patch it as it changes over time - see the next section). You'll also receive this message when a control page's remote display property is changed from False to True.

update control page message

The update control page message is received when a control page has been updated on the Indigo server. It doesn't allow users to update control pages via the WebSocket API.

{
  "message": "patch", // we use a patch rather than send the entire updated control page
  "objectType": "indigo.ControlPage",
  "patch": {}  // A patch object - see the Object Patches below for details
}

Page patch objects are created via the dictdiffer python module, by comparing the device dictionary (dict(some_page)) for the old page with the one for the new dictionary as they are received in the control_page_updated() Plugin method call.

delete control page message
{
  "message": "delete",
  "objectType": "indigo.ControlPage",
  "objectId": 123456789
}

This is the simplest of the messages, as it just contains the Indigo ID of the control page to delete from your collection. You'll receive this message when a control page is deleted from the Indigo server and when a control page's remote display property is set from True to False.

Indigo Object Folders

Each object type above may have folders. Since those folders are specific to the type, you will use the same feed (i.e. device-feed, etc.) to get all of the available folders for that type.

This is an example of a folder object. It is the same for any folder in any feed - children is the generic name for the indigo objects contained in the folder (device, variable, etc).

{
  "id": 617272302,
  "class": "indigo.Folder",
  "name": "My Device Folder",
  "remoteDisplay": true
}

refresh folder server message

To get the full folder list from the server, send the following message.

{
  "message": "refresh",
  "id": "optional-user-generated-id", // This is just a pass through from the refresh request
  "objectType": "indigo.Device.Folder",
}

You will then receive the following message with all of the folders for that Indigo object type.

{
  "message": "refresh",
  "id": "optional-user-generated-id", // This is just a pass through from the refresh request
  "objectType": "indigo.Device.Folder", // or indigo.Variable.Folder, etc
  "list": []  // A list of folder objects defined above
}

As of this release, this is the only way to get the current state of folders (there are not add/update/delete messages). If you think you need to refresh your folder list, then send the refresh message. Since folders are generally static, there really isn't much need to continually get the folder list.

Log Feed

Use this feed to catch all log messages as they happen in the Indigo Server. When you first open the log-feed WebSocket, you will receive the last 25 log messages from the server in chronological order. After that, the messages come through the socket as they are generated (chronological order). See the Log Messages section below for a description of a log message object.

Here are the URLs you will use to connect to this feed:

ws://localhost:8176/v2/api/ws/log-feed
wss://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/ws/log-feed

You won't be able to send the server any messages on the log-feed, and the only message you get will be an add message for every new log entry:

{
  "message": "add",
  "objectType": "indigo.LogEvent",
  "objectDict": {
    "message": "Stopping plugin \"Web Server 2022.2.0\" (pid 1020)",
    "timeStamp": "2022-12-01T12:03:27.759000",
    "typeStr": "Application",
    "typeVal": 0
    "objectType": "indigo.LogEvent"
  }
}

HTTP API

This API is meant for use with standard HTTP as the communication mechanism. HTTP GET requests to get Indigo object instances in JSON format, and POST requests to send commands to the Indigo Server.

HTTP API Endpoints

The following is a summary of endpoints (URLs that you will need to use the API) that are available in this release (detail on each is further down):

  • /v2/api/indigo.devices - endpoint to get a list of devices
  • /v2/api/indigo.devices/123456789 - endpoint to get a specific device instance (See Device Objects below)
  • /v2/api/indigo.variables - endpoint to get a list of variables
  • /v2/api/indigo.variables/123456789 - endpoint to specific variable object (See Variable Objects below)
  • /v2/api/indigo.actionGroups - endpoint to get a list of action groups
  • /v2/api/indigo.actionGroups/123456789 - endpoint to get a specific action group (See Action Group Objects below)
  • /v2/api/command - endpoint to send Indigo a command (device control, variable update, action execution).

You’ll receive full JSON objects which represent either a list of all instances of the object type requested (for example, a list of all action groups) or an individual Indigo object instance (a single device, variable, etc.) Each individual object will be different based on the object type, class and its definition (a custom device, for example). See the Indigo Object Model docs for details about each object type.

Authentication

HTTP API requests must be authenticated using an API Key. You can manage API Keys in the Authorizations section of your Indigo Account. Using keys instead of your Indigo Server username/password has several advantages: you can, at any time, revoke an API key, and it will immediately cause anything using it to fail. This will not affect anything else using your username/password or another API key, so your server protections against intrusions are much more granular. Also, if someone does manage to get your API Key, they can control devices, but they cannot modify your database (add/delete devices, etc) - that is reserved for Indigo clients using the username/password.

The best way to use an API Key is to include it in an Authorization header on your HTTP request. All the examples below show this approach. If you are using a system which does not allow you to set headers for your HTTP request, you can include the API Key as a query argument with the URL:

https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/indigo.devices/123456789?api-key=YOUR-API-KEY

When using HTTPS, such as when you are using your Indigo Reflector, then your API Key (in both instances) is protected by the TLS security used by the HTTPS protocol. You may use the API locally (or thorough your own router port forwarding), but those connections will be HTTP and will not be secure. It is highly recommended that you always use your Indigo Reflector because it provides a very simple and secure solution for accessing your system. IMPORTANT! Be sure not to share your API keys with anyone not authorized to use them — especially in posts to the user forums.

Getting Device Objects

The HTTP API includes a couple of methods for getting device instances as JSON objects.

Getting All Device Objects

Device Objects are JSON representations of an Indigo device instance. This JSON object will contain all information about the object, which you can use in your solutions. By using the endpoint without specifying a specific device id, you can get the complete list of all devices in your Indigo database:

/v2/api/indigo.devices

Here are some examples in different languages/technologies that illustrate how to get all devices.

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/indigo.devices")
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    device_list = json.load(request)
    print(device_list)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: `/v2/api/indigo.devices`,
  headers: {
    Authorization: `Bearer ${APIKEY}`
  }
}
 
// Get the device JSON from Indigo, parse it into an object, and log it to the console
http.get(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const deviceList = JSON.parse(result);
    console.log(deviceList);
  })
})
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
curl -H "Authorization: Bearer YOUR-API-KEY" https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/indigo.devices

Getting a Single Device Object

Here are a few examples in different languages that illustrate how to get device objects.

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
DEVICEID = 123456789
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/indigo.devices/{DEVICEID}")
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    device_instance = json.load(request)
    print(device_instance)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
const DEVICEID = 123456789
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: `/v2/api/indigo.devices/${DEVICEID}`,
  headers: {
    Authorization: `Bearer ${APIKEY}`
  }
}
 
// Get the device JSON from Indigo, parse it into an object, and log it to the console
http.get(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const deviceInstance = JSON.parse(result);
    console.log(deviceInstance);
  })
})
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
curl -H "Authorization: Bearer YOUR-API-KEY" https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/indigo.devices/123456789

Controlling an Indigo Device

You can control Indigo devices by sending commands through the API that instruct Indigo how to control the device. Indigo devices come in a variety of types, and each type has its own command set. See the Device Command Messages below for a description of all messages. For now, here are some simple examples to toggle devices:

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
DEVICEID = 123456789
 
# The message to send to the Indigo Server
message = json.dumps({
    "id": "optional-user-generated-id",
    "message": "indigo.device.toggle",
    "objectId": DEVICEID
}).encode("utf8")
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/command", data=message)
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    reply = json.load(request)
    print(reply)
JavaScript toggle from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
const DEVICEID = 123456789
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// The message to send to the Indigo Server
const message = JSON.stringify({
    "id": "optional-user-generated-id",
    "message": "indigo.device.toggle",
    "objectId": DEVICEID
})
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: "/v2/api/command",
  method: "POST",
  headers: {
    Authorization: `Bearer ${APIKEY}`,
    "Content-Length": message.length
  }
}
 
// Get the device JSON from Indigo, parse it into an object, and log it to the console
const req = http.request(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const deviceInstance = JSON.parse(result);
    console.log(deviceInstance);
  })
})
req.write(message)
req.end()
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
curl -X POST -H "Authorization: Bearer YOUR-API-KEY" -d '{"message": "indigo.device.toggle", "objectId": 123456789}' https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/command

Using these examples, you can now construct any command listed below for any device type.

Controlling an Indigo Device with Parameters

As noted above, Indigo devices come in a variety of types, and each type has its own command set. As a part of this command set, some devices require specific parameters in order for Indigo to be able to execute them (some devices accept optional parameters, and others do not require any parameters at all). See the Device Command Messages below for a description of all messages. The following examples use the indigo.dimmer.setBrightness command and demonstrate how to include parameters.

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
DEVICEID = 123456789
 
# The message to send to the Indigo Server
message = json.dumps({
  "id": "optional-user-generated-id",
  "message": "indigo.dimmer.setBrightness",
  "objectId": DEVICEID,
  "parameters": {
    "value": 50,
    "delay": 10
  }
}).encode("utf8")
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/command", data=message)
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    reply = json.load(request)
    print(reply)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
const DEVICEID = 123456789
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// The message to send to the Indigo Server
const message = JSON.stringify({
  "id": "optional-user-generated-id",
  "message": "indigo.dimmer.setBrightness",
  "objectId": DEVICEID,
  "parameters": {
    "value": 50,
    "delay": 10
  }
})
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: "/v2/api/command",
  method: "POST",
  headers: {
    Authorization: `Bearer ${APIKEY}`,
    "Content-Length": message.length
  }
}
 
// Get the device JSON from Indigo, parse it into an object, and log it to the console
const req = http.request(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const deviceInstance = JSON.parse(result);
    console.log(deviceInstance);
  })
})
req.write(message)
req.end()
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo device ID.
curl -X POST -H "Authorization: Bearer YOUR-API-KEY" -d '{"message": "indigo.dimmer.setBrightness", "objectId": 123456789, "parameters": {"value": 50, "delay": 10}}' https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/command

Using these examples, you can now construct any command listed below for any device type.

Getting Variable Objects

Getting All Variable Objects

Variable Objects are JSON representations of an Indigo variable instance. This JSON object will contain all information about the object, which you can use in your solutions. By using the endpoint without specifying a specific variable id, you can get the complete list of all variables in your Indigo database:

/v2/api/indigo.variables

Here are some examples in different languages/technologies that illustrate how to get all variables.

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/indigo.variables")
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    variable_list = json.load(request)
    print(variable_list)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: `/v2/api/indigo.variables`,
  headers: {
    Authorization: `Bearer ${APIKEY}`
  }
}
 
// Get the variable JSON from Indigo, parse it into an object, and log it to the console
http.get(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const VariableList = JSON.parse(result);
    console.log(VariableList);
  })
})
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
curl -H "Authorization: Bearer YOUR-API-KEY" https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/indigo.variables

Getting a Single Variable Object

Here are a few examples in different languages that illustrate how to get variable objects.

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo variable ID.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
VARID = 123456789  # Indigo variable object id
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/indigo.variables/{VARID}")
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    var_instance = json.load(request)
    print(var_instance)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo variable ID.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
const VARID = 123456789
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: `/v2/api/indigo.variables/${VARID}`,
  headers: {
    Authorization: `Bearer ${APIKEY}`
  }
}
 
// Get the variable object JSON from Indigo, parse it into an object, and log it to the console
http.get(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const varInstance = JSON.parse(result);
    console.log(varInstance);
  })
})
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo variable ID.
curl -H "Authorization: Bearer YOUR-API-KEY" https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/indigo.variables/123456789

Updating a Variable's Value

You can interact with Indigo variables by sending commands through the API that instruct Indigo what to do. There is only one type of Indigo variable, and the variable type has its own command set. See the Variable Command Messages below for a description of all messages. For now, here is an example of how to set the value of a variable:

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo variable ID.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
VARIABLEID = 123456789
 
# The message to send to the Indigo Server
message = json.dumps({
  "id": "optional-user-generated-id",
  "message": "indigo.variable.updateValue",
  "objectId": VARIABLEID,
  "parameters": {
    "value": "Some string value"
  }
}).encode("utf8")
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/command", data=message)
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    reply = json.load(request)
    print(reply)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo variable ID.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
const VARIABLEID = 123456789
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// The message to send to the Indigo Server
const message = JSON.stringify({
  "id": "optional-user-generated-id",
  "message": "indigo.variable.updateValue",
  "objectId": VARIABLEID,
  "parameters": {
    "value": "Some string value"
  }
})
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: "/v2/api/command",
  method: "POST",
  headers: {
    Authorization: `Bearer ${APIKEY}`,
    "Content-Length": message.length
  }
}
 
// Get the variable JSON from Indigo, parse it into an object, and log it to the console
const req = http.request(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const VariableInstance = JSON.parse(result);
    console.log(VariableInstance);
  })
})
req.write(message)
req.end()
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo variable ID.
curl -X POST -H "Authorization: Bearer YOUR-API-KEY" -d '{"message": "indigo.variable.updateValue", "objectId": 123456789, "parameters": {"value": "Some string value"}}' https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/command

Using these examples, you can now construct any command listed below for any variable type.

Getting Action Group Objects

Getting All Action Group Objects

Action Group Objects are JSON representations of an Indigo action group instance. This JSON object will contain all information about the object, which you can use in your solutions. By using the endpoint without specifying a specific action group id, you can get the complete list of all action groups in your Indigo database:

/v2/api/indigo.actionGroups

Here are some examples in different languages/technologies that illustrate how to get all action groups.

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/indigo.actionGroups")
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    action_group_list = json.load(request)
    print(action_group_list)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: `/v2/api/indigo.actionGroups`,
  headers: {
    Authorization: `Bearer ${APIKEY}`
  }
}
 
// Get the action group JSON from Indigo, parse it into an object, and log it to the console
http.get(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const actionGroupList = JSON.parse(result);
    console.log(actionGroupList);
  })
})
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
curl -H "Authorization: Bearer YOUR-API-KEY" https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/indigo.actionGroups

Executing an Action Group

You can control Indigo action groups by sending commands through the API that instruct Indigo how to execute the action group. There is only one type of Indigo action group, and the action group type has its own command set. See the Action Group Command Messages below for a description of all messages. For now, here is a simple example of how to execute an action group:

Pure Python 3 (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo action group ID.
# This is a pure python example - no additional libraries needed
from urllib.request import Request, urlopen
import json
 
REFLECTORNAME = "YOUR-REFLECTOR-NAME"
APIKEY = "YOUR-API-KEY"
ACTIONGROUPID = 123456789
 
# The message to send to the Indigo Server
message = json.dumps({
  "id": "optional-user-generated-id",
  "message": "indigo.actionGroup.execute",
  "objectId": ACTIONGROUPID
}).encode("utf8")
 
req = Request(f"https://{REFLECTORNAME}.indigodomo.net/v2/api/command", data=message)
req.add_header('Authorization', f"Bearer {APIKEY}")
with urlopen(req) as request:
    reply = json.load(request)
    print(reply)
JavaScript run from nodejs (no additional libraries)
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo action group ID.
// Things that are specific to your environment
const REFLECTORNAME = "YOUR-REFLECTOR-NAME"
const APIKEY = "YOUR-API-KEY"
const ACTIONGROUPID = 123456789
 
// Get the http module, and tell it that you're using HTTPS
const http = require("https")
 
// The message to send to the Indigo Server
const message = JSON.stringify({
  "id": "optional-user-generated-id",
  "message": "indigo.actionGroup.execute",
  "objectId": ACTIONGROUPID
})
 
// These are options that you'll pass to the get call
const options = {
  hostname: `${REFLECTORNAME}.indigodomo.net`,
  path: "/v2/api/command",
  method: "POST",
  headers: {
    Authorization: `Bearer ${APIKEY}`,
    "Content-Length": message.length
  }
}
 
// Get the action group JSON from Indigo, parse it into an object, and log it to the console
const req = http.request(options, (response) => {
  let result = ""
  response.on("data", chunk => {
    result += chunk;
  })
  response.on("end", () => {
    const actionGroupInstance = JSON.parse(result);
    console.log(actionGroupInstance);
  })
})
req.write(message)
req.end()
Using curl from the command line
  • Replace YOUR-API-KEY with a valid key from your Indigo account.
  • Replace YOUR-REFLECTOR-NAME with the reflector name for your Indigo server.
  • Replace 123456789 with a valid Indigo action group ID.
curl -X POST -H "Authorization: Bearer YOUR-API-KEY" -d '{"message": "indigo.actionGroup.execute", "objectId": 123456789}' https://YOUR-REFLECTOR-NAME.indigodomo.net/v2/api/command

Using these examples, you can now construct any command listed below for any action group type.

API Messages

As mentioned earlier, both the WebSocket and HTTP APIs use JSON as the message format. We have exposed JSON versions of main Indigo objects: devices, variables, action groups, and control pages. We are also exposing command messages, which parallel the IOM command namespaces (where appropriate) for each of these object types (i.e. indigo.device, indigo.variable, etc), which will allow you to command devices, set variable values, execute action groups, etc.

There are also two other message types: event log messages, which represent each message that flow into the Event Log window, and error messages, which is a standardized way to communicate error conditions with each API.

In this section, we will give examples of each message type and describe their use.

If you are new to JSON, you might want to use the JSON Validator website to validate that your JSON messages are valid JSON.

Device Messaging

This section describes the messages that you'll use when implementing either the WebSocket or HTTP APIs. They fall into two categories: device objects and device commands.

Device Objects

You’ll receive full device JSON objects which represent an Indigo device instance. Each device will be slightly different based on the device class and the definition (if a custom device). See the Indigo Object Model docs for device details.

Example device object

This is an example of an Indigo device as a JSON object. Of course, to accommodate the wide variety of supported device types, each one will be somewhat different. This one represents an Insteon Dimmer.

{
  "class": "indigo.DimmerDevice",
  "address": "3B.04.7A",
  "batteryLevel": null,
  "blueLevel": null,
  "brightness": 0,
  "buttonConfiguredCount": 0,
  "buttonGroupCount": 1,
  "configured": true,
  "defaultBrightness": 100,
  "description": "- sample device -",
  "deviceTypeId": "",
  "displayStateId": "brightnessLevel",
  "displayStateImageSel": "indigo.kStateImageSel.DimmerOff",
  "displayStateValRaw": 0,
  "displayStateValUi": "0",
  "enabled": true,
  "energyAccumBaseTime": null,
  "energyAccumTimeDelta": null,
  "energyAccumTotal": null,
  "energyCurLevel": null,
  "errorState": "",
  "folderId": 1552926800,
  "folder": {
    "class": "indigo.Folder",
    "id": 1552926800,
    "name": "Insteon",
    "remoteDisplay": true
  },
  "globalProps": {},
  "greenLevel": null,
  "id": 1508839119,
  "lastChanged": "2023-02-01T11:39:58",
  "lastSuccessfulComm": "2023-02-01T11:39:58",
  "ledStates": [],
  "model": "LampLinc (dual-band)",
  "name": "Insteon Dimmer",
  "onBrightensToDefaultToggle": true,
  "onBrightensToLast": false,
  "onState": false,
  "ownerProps": {},
  "pluginId": "",
  "pluginProps": {},
  "protocol": "indigo.kProtocol.Insteon",
  "redLevel": null,
  "remoteDisplay": false,
  "sharedProps": {},
  "states": {
    "brightnessLevel": 0,
    "onOffState": false
  },
  "subModel": "Plug-In",
  "subType": "Plug-In",
  "supportsAllLightsOnOff": true,
  "supportsAllOff": true,
  "supportsColor": false,
  "supportsOnState": true,
  "supportsRGB": false,
  "supportsRGBandWhiteSimultaneously": false,
  "supportsStatusRequest": true,
  "supportsTwoWhiteLevels": false,
  "supportsTwoWhiteLevelsSimultaneously": false,
  "supportsWhite": false,
  "supportsWhiteTemperature": false,
  "version": 67,
  "whiteLevel": null,
  "whiteLevel2": null,
  "whiteTemperature": null
}

Message that contain device objects generate those objects by first converting the device to a python dictionary and then converting the python dictionary to JSON. See the Generating a Dictionary for a device section of the IOM Reference for details.

HTTP The folder element is only available in the HTTP API. Folders are handled differently in the WebSocket API.

Device Command Messages

One thing you will notice as you are looking through these examples, is that they closely mirror the Python-based IOM commands for controlling devices. This was intentional to make learning one API a stepping stone to another. The HTTP API messages and the WebSocket API messages are identical, and are very clearly a JSON-rendered version of the associated IOM command.

The id key is optional, but may contain a user generated ID that will be logged and returned to help match up with message requests.

indigo.device

indigo.device command messages can be used for several Indigo device types - indigo.RelayDevice, indigo.DimmerDevice, indigo.SpeedControl (fans), and some indigo.SensorDevice instances.

status request indigo.device.statusRequest(123456789)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.statusRequest",
  "objectId": 123456789
}

Note: This message will work on any Indigo device type, though the device that it targets may not respond to status request messages in which case it will do nothing.

WebSocket This won't necessarily cause a device update message - if the device didn't have any changes after the status request, there will be no updates to the device in the server, so no update message will be sent out the websocket.

toggle indigo.device.toggle(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.toggle",
  "objectId": 123456789,
  "parameters": {
    "delay": 5,
    "duration": 10
  }
}

objectId is the id of the device. The parameters dictionary is optional.

turn off indigo.device.turnOff(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.turnOff",
  "objectId": 123456789,
  "parameters": {
    "delay": 5,
    "duration": 10
  }
}

objectId is the id of the device. The parameters dictionary is optional.

turn on indigo.device.turnOn(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.turnOn",
  "objectId": 123456789,
  "parameters": {
    "delay": 5,
    "duration": 10
    }
}

objectId is the id of the device. The parameters dictionary is optional.

lock indigo.device.lock(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.lock",
  "objectId": 123456789,
  "parameters": {
    "delay": 5,
    "duration": 10
  }
}

objectId is the id of the device. The parameters dictionary is optional.

unlock indigo.device.unlock(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.unlock",
  "objectId": 123456789,
  "parameters": {
    "delay": 5,
    "duration": 10
  }
}

objectId is the id of the device. The parameters dictionary is optional.

enable/disable indigo.device.enable(123456789, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.device.enable",
  "objectId": 123456789,
  "parameters": {
    "value": True,
  }
}

objectId is the id of the device. The value parameter is optional (True to enable, False to disable).

indigo.dimmer

indigo.dimmer command messages can be used for indigo.DimmerDevice instances.

brighten indigo.dimmer.brighten(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.dimmer.brighten",
  "objectId": 123456789,
  "parameters": {
    "by": 5,
    "delay": 10
  }
}

objectId is the id of the device. The parameters dictionary is optional.

dim indigo.dimmer.dim(123456789, delay=5, duration=10)

{
  "id": "optional-user-generated-id",
  "message": "indigo.dimmer.dim",
  "objectId": 123456789,
  "parameters": {
    "by": 5,
    "delay": 10
  }
}

objectId is the id of the device. The parameters dictionary is optional.

set brightness indigo.dimmer.setBrightness(123456789, value=50, delay=5)

{
  "id": "optional-user-generated-id",
  "message": "indigo.dimmer.setBrightness",
  "objectId": 123456789,
  "parameters": {
    "value": 50,
    "delay": 10
  }
}

objectId is the id of the device. The value parameter is required and the delay parameter is optional.

indigo.iodevice

indigo.iodevice command messages can be used for indigo.MultiIODevice instances.

set binary output indigo.iodevice.setBinaryOutput(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.iodevice.setBinaryOutput",
  "objectId": 123456789,
  "parameters": {
    "index": 5,
    "value": true
  }
}

objectId is the id of the device. The index and value parameters are required.

indigo.sensor

indigo.sensor command messages can be used for indigo.sensorDevice instances.

set on state indigo.sensor.setOnState(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sensor.setOnState",
  "objectId": 123456789,
  "parameters": {
    "value": true
  }
}

objectId is the id of the device. The value parameter is required.

indigo.speedcontrol

indigo.speedcontrol command messages can be used for indigo.speedcontrol instances.

decrease speed index indigo.speedcontrol.decreaseSpeedIndex(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.speedcontrol.decreaseSpeedIndex",
  "objectId": 123456789,
  "parameters": {
    "by": 2,
    "delay": 5
  }
}

objectId is the id of the device. The by and delay parameters are optional.

increase speed index indigo.speedcontrol.increaseSpeedIndex(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.speedcontrol.increaseSpeedIndex",
  "objectId": 123456789,
  "parameters": {
    "by": 2,
    "delay": 5
  }
}

objectId is the id of the device. The by and delay parameters are optional.

set speed index indigo.speedcontrol.setSpeedIndex(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.speedcontrol.setSpeedIndex",
  "objectId": 123456789,
  "parameters": {
    "value": 2,
    "delay": 5
  }
}

objectId is the id of the device. The value parameter is required and the delay parameter is optional.

set speed level indigo.speedcontrol.setSpeedLevel(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.speedcontrol.setSpeedLevel",
  "objectId": 123456789,
  "parameters": {
    "value": 50,
    "delay": 5
  }
}

objectId is the id of the device. The value parameter is required and the delay parameter is optional.

indigo.sprinkler

indigo.sprinkler command messages can be used for indigo.sprinkler instances.

next zone indigo.sprinkler.nextZone(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.nextZone",
  "objectId": 123456789
}

objectId is the id of the device. The next zone command does not have any additional parameters.

pause schedule indigo.sprinkler.pause(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.pause",
  "objectId": 123456789
}

objectId is the id of the device. The next zone command does not have any additional parameters.

previous zone indigo.sprinkler.previousZone(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.previousZone",
  "objectId": 123456789
}

objectId is the id of the device. The previous zone command does not have any additional parameters.

resume schedule indigo.sprinkler.resume(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.resume",
  "objectId": 123456789
}

objectId is the id of the device. The resume schedule command does not have any additional parameters.

run schedule indigo.sprinkler.run(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.run",
  "objectId": 123456789,
  "parameters": {
    "schedule": [10,15,8, 0, 0, 0, 0, 0]
  }
}

objectId is the id of the device. The schedule parameter is required.

stop schedule indigo.sprinkler.stop(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.stop",
  "objectId": 123456789
}

objectId is the id of the device. The resume schedule command does not have any additional parameters.

set active zone indigo.sprinkler.setActiveZone(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.sprinkler.setActiveZone",
  "objectId": 123456789,
  "parameters": {
    "index": 2
  }
}

objectId is the id of the device. The index parameter is required.

indigo.thermostat

indigo.thermostatdevice command messages can be used for indigo.thermostat instances.

decrease cool setpoint indigo.thermostat.decreaseCoolSetpoint(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.decreaseCoolSetpoint",
  "objectId": 123456789,
  "parameters": {
    "delta": 2
  }
}

objectId is the id of the device. The value parameter is optional.

decrease heat setpoint indigo.thermostat.decreaseHeatSetpoint(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.decreaseHeatSetpoint",
  "objectId": 123456789,
  "parameters": {
    "delta": 2
  }
}

objectId is the id of the device. The value parameter is optional.

increase cool setpoint indigo.thermostat.increaseCoolSetpoint(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.increaseCoolSetpoint",
  "objectId": 123456789,
  "parameters": {
    "delta": 2
  }
}

objectId is the id of the device. The value parameter is optional.

increase heat setpoint indigo.thermostat.increaseHeatSetpoint(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.increaseHeatSetpoint",
  "objectId": 123456789,
  "parameters": {
    "delta": 2
  }
}

objectId is the id of the device. The value parameter is optional.

set cool setpoint indigo.thermostat.setCoolSetpoint(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.setCoolSetpoint",
  "objectId": 123456789,
  "parameters": {
    "value": 76
  }
}

objectId is the id of the device. The value parameters is required.

set fan mode indigo.thermostat.setFanMode(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.setFanMode",
  "objectId": 123456789,
  "parameters": {
    "value": "indigo.kFanMode.AlwaysOn"
  }
}

objectId is the id of the device. The value parameter is required.

set heat setpoint indigo.thermostat.setHeatSetpoint(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.setHeatSetpoint",
  "objectId": 123456789,
  "parameters": {
    "value": 76
  }
}

objectId is the id of the device. The value parameter is required.

set hvac mode indigo.thermostat.setHvacMode(123456789, index=2, value=True)

{
  "id": "optional-user-generated-id",
  "message": "indigo.thermostat.setHvacMode",
  "objectId": 123456789,
  "parameters": {
    "value": "indigo.kHvacMode.HeatCool"
  }
}

objectId is the id of the device. The value parameter is required.

Variable Messaging

This section describes the messages that you'll use when implementing either the WebSocket or HTTP APIs when dealing with Indigo devices. They fall into two categories: device objects and device command messages.

Variable Objects

You’ll receive full variable JSON objects which represent an Indigo variable instance. See the Indigo Object Model docs for device details.

Example variable object
{
  "class": "indigo.Variable",
  "description": "",
  "folderId": 0,
  "folder": {},
  "globalProps": {
    "com.indigodomo.indigoserver": {}
  },
  "id": 345633244,
  "name": "house_status",
  "pluginProps": {},
  "readOnly": false,
  "remoteDisplay": true,
  "sharedProps": {},
  "value": "home"
}

Messages that contain variable objects generate those objects by first converting the variable to a python dictionary and then converting the python dictionary to JSON. See the Generating a Dictionary for a variable section of the IOM Reference for details.

HTTP The folder element is only available in the HTTP API. Folders are handled differently in the WebSocket API.

Variable Command Messages

The only action that can currently be performed on a variable is to update the value. The id key is optional, but may contain a user generated ID that will be logged and returned to help match up with message requests.

updateValue indigo.variable.updateValue(123456789, value="Some string value")

{
  "id": "optional-user-generated-id",
  "message": "indigo.variable.updateValue",
  "objectId": 123456789,
  "parameters": {
    "value": "Some string value"
  }
}

objectId is the id of the variable. The value parameter is required and must be a string. Pass an empty string (“”) to clear the variable value.

Action Group Messaging

Action Group Objects

You’ll receive full variable JSON objects which represent an Indigo action group instance. See the Indigo Object Model docs for action group details.

Example action group object
{
  "class": "indigo.ActionGroup",
  "description": "",
  "folderId": 532526508,
  "folder": {
    "class": "indigo.Folder",
    "id": 532526508,
    "name": "Mood Scenes",
    "remoteDisplay": true
  },
  "globalProps": {
    "com.indigodomo.indigoserver": {
      "speakDelayTime": "5",
      "speakTextVariable": "speech_string"
    }
  },
  "id": 94914463,
  "name": "Movie Night",
  "pluginProps": {},
  "remoteDisplay": true,
  "sharedProps": {
    "speakDelayTime": "5",
    "speakTextVariable": "speech_string"
  }
}

HTTP The folder element is only available in the HTTP API. Folders are handled differently in the WebSocket API.

Action Group Command Messages

There is only a single action group command, and that's to execute it. The id key is optional, but may contain a user generated ID that will be logged and returned to help match up with message requests.

execute indigo.actionGroup.execute(123456789)

{
  "id": "optional-user-generated-id",
  "message": "indigo.actionGroup.execute",
  "objectId": 123456789
}

objectId is the id of the action group.

Log Messages

We convert the event Indigo dictionary into a python dictionary in the event_log_line_received plugin method.

Example Log Message

{
  "message": "Stopping plugin \"Web Server 2022.2.0\" (pid 1020)",
  "timeStamp": "2022-12-01T12:03:27.759000",
  "typeStr": "Application",
  "typeVal": 0
  "objectType": "indigo.LogEvent"
}

Note that typeVal will be one of the following values:

EVENT_TYPES = {
  Application = 0,
  Error = 1,
  Error_Client = 2,
  Warning = 3,
  Warning_Client = 4,
  Debug_Server = 5,
  Debug_Client = 6,
  Debug_Plugin = 7,
  Custom = 8,
}

You can use the values above to help determine any kind of decoration you want to use when displaying or otherwise interpreting the log event.

Error Messaging

Error messages will be returned to API clients in the event that something didn’t go as planned. The structure of messages returned will depend on what went wrong and how the message was sent. Note that folder messages are added to the feed by the server; there are no folder endpoints to manage folders from a client at this time.

A generic example message is provided in JSON format:

Generic Error Message
{
  "error": "Some error description",
  "id": "the id sent from the client in the message, or null if there wasn't one",
  "validationErrors": {
    "field1": "some error that occurred in the message with the key field1"
  }
}

where the value of the JSON name (or key) validationErrors is a dictionary with a field name and a description of the error in that field that came from the client. For instance, if you pass a float value to the indigo.variable.updateValue message:

Example API Call
{
  "id": "a-random-id-for-this-message",
  "message": "indigo.variable.updateValue",
  "objectId": 123456789,
  "parameters": {
    "value": 1234.56
  }
}

You will receive the following error response:

Resulting Error Message
{
  "validationErrors": {
    "value": "variable values must be strings"
  },
  "error": "invalid command payload received, id: my-set-var-command",
  "id": "a-random-id-for-this-message"
}

The error key is the indicator that the response is some kind of error. validationErrors is a dict which contains all the validation errors for the message, in this case the value that was passed in was not a string (it was the float 1234.56). The possible keys in the error message reply validationErrors could be:

  1. message,
  2. objectId,
  3. parameters, and
  4. value

based on the indigo.variable.updateValue message format (we do no validation on the id value passed in, we pass it through, and if your message doesn’t contain one then the value will be null). Only the keys from your message that have errors will be returned. So in the example error above, only the value key had a validation error (because we passed in a float) so that was the only key returned.

id is the ID you (may have) passed in when you sent the command message.

Invalid JSON

One other type of error that you may receive would be if you POST a string (or something else, like XML, etc.) that’s not JSON. This will result in the following message return:

Example Invalid JSON Message
{
  "request_body": "this is not valid JSON",
  "error": "invalid JSON"
}

We will return the entire request body since it isn’t valid JSON, and we don’t know what else to do with it.

indigo_2022.2_documentation/api.txt · Last modified: 2023/07/15 16:40 by davel17
 

© Perceptive Automation, LLC. · Privacy