# Welcome to the Web API documentation 👋

🌍 Learn how to build great integrations for Homey Pro & Homey Cloud.

The Homey Web API is a HTTP + Socket.IO API to control Devices, start Flows, view Insights and more. It is used by Athom internally for the [Homey Mobile App](https://get.homey.app), [Homey Web App](https://my.homey.app), [Alexa](https://www.amazon.com/Athom-B-V-Homey/dp/B078RQSFKB), [Google Assistant](https://assistant.google.com/services/a/uid/000000ff72e71f6d), and is available to 3rd party developers to create their own integrations.

As opposed to the apps running *on* Homey Pro or Homey Cloud, using the [Homey Apps SDK](https://apps.developer.homey.app/), integrating with the Homey Web API requires your own server or front-end.

The Web API can also used from within a HomeyScript. [Learn more »](https://homey.app/a/com.athom.homeyscript)

Homey Pro apps with the `homey:manager:api` permission can also use some endpoints from within their app. [Learn more »](https://athombv.github.io/node-homey-api/HomeyAPI.html#.createAppAPI)

### Creating a Web API Client

Before you can get started, you need to create your own Web API Client, to receive your Client ID & Secret.

Customers must authenticate using OAuth2 with your application, before you can make API calls on their behalf.

{% hint style="success" %}
Create your own API Client in the [Homey Developer Tools](https://tools.developer.homey.app/api/clients).
{% endhint %}

{% hint style="warning" %}
New API Clients are limited to a maximum of 100 Homey Pro users. To remove this limit, and optionally connect to Homey Cloud, click the *Request Limit Increase* link in the Developer Tools. We will try to handle your request as soon as possible.
{% endhint %}

### Example

We provide a JavaScript & Node.js library, [node-homey-api](https://www.npmjs.com/package/homey-api), to take care of the heavy lifting by authenticating & connecting to a customer's Homey Pro or Homey Cloud.

If you're not developing within a JavaScript environment, please visit [HTTP Specification](/http-and-socket.io/http-specification).&#x20;

```javascript
const AthomCloudAPI = require('homey-api/lib/AthomCloudAPI');

// Create a Cloud API instance
const cloudApi = new AthomCloudAPI({
  clientId: '...',
  clientSecret: '...',
});

// Get the logged in user
const user = await cloudApi.getAuthenticatedUser();

// Get the first Homey of the logged in user
const homey = await user.getFirstHomey();

// Create a session on this Homey
const homeyApi = await homey.authenticate();

// Loop all devices
const devices = await homeyApi.devices.getDevices();
for(const device of Object.values(devices)) {
  // Turn device on
  await device.setCapabilityValue({ capabilityId: 'onoff', value: true }); 
}

// Connect to receive realtime events
await homeyApi.devices.connect();
homeyApi.devices.on("device.delete", (device) => {
  // Device deleted
});
homeyApi.devices.on("device.update", (device) => {
  // Device updated
});
homeyApi.devices.on("device.create", (device) => {
  // Device created
});
```

## 👥 Community

* Questions? Ask them on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=homey) with the `homey` tag.
* Please report any issues you find in the [Web API Issue Tracker](https://github.com/athombv/homey-web-api-issues/issues).


# HTTP Specification

While we provide a fully featured [Web API Client for JavaScript](https://www.npmjs.com/package/homey-api) (Browser, Node.js) environments, we understand that you might prefer another programming language. This guide is to help you get started with the core concepts to build your own Web API connection by only using HTTP + Socket.io.

## Authenticating with Athom Cloud API

The Homey Web API uses OAuth2 to authorise Homey users with your OAuth2 client. They give your application delegated permission to act on their behalf.

### Step 1 — Getting an Authorization Code

First, your application needs to redirect a user to `https://api.athom.com/oauth2/authorise`  with the following query parameters:

| Name                 | Value                                                                                                          |
| -------------------- | -------------------------------------------------------------------------------------------------------------- |
| `authorization_type` | `code`                                                                                                         |
| `client_id`          | Your Client ID                                                                                                 |
| `redirect_uri`       | Your Redirect URI                                                                                              |
| `state`              | Optional. This can be any string, and will be returned once the user has been redirected to your Redirect URI. |

For example:

```
https://api.athom.com/oauth2/authorise?authorization_type=code&client_id=abcd&redirect_uri=https://example.com/oauth2/callback&state=my_state
```

Once the user has approved the request, they will be redirected to your client's Redirect URI, with the `code` query parameter.

For example:

```
https://example.com/oauth2/callback?code=abcdef&state=my_state
```

### Step 2 — Exchanging the Authorization Code for a Token

In the back-end of your app, you can now exchange the Authorization Code for a Token. The Authorization Code is valid for only 30 seconds, whereas the Token will be valid forever, or until the user revokes it.

Your back-end should make a HTTP POST request to `https://api.athom.com/oauth2/token` with the following `application/x-www-form-urlencoded` parameters.

#### URL

`https://api.athom.com/oauth2/token`

#### Headers

| Name            | Value                                           |
| --------------- | ----------------------------------------------- |
| `Content-Type`  | `application/x-www-form-urlencoded`             |
| `Authorization` | `Basic base64(Client ID + ':' + Client Secret)` |

#### Body

| Name                 | Value                               |
| -------------------- | ----------------------------------- |
| `grant_type`         | `authorization_code`                |
| `authorization_code` | The `code` you retrieved in Step 1. |

For example, the HTTP request should look like this:

```http
POST /oauth2/token HTTP/1.1
Authorization: Basic ZXhhbXBsZTpleGFtcGxl
Content-Type: application/x-www-form-urlencoded
Host: api.athom.com
Connection: close
Content-Length: 56

grant_type=authorization_code&authorization_code=example 
```

When successful, the result will be a JSON-encoded object that looks like this:

```json
{
  "token_type": "bearer",
  "grant_type": "authorization_code",
  "access_token": "abc...",
  "refresh_token": "abc...",
  "expires_in": "3660"
}
```

You can now make API calls to `https://api.athom.com` with a header `Authorization: Bearer <access_token>`.

### Step 3 — Refreshing the Token

For security purposes, the access token will expire after one hour. The refresh token will never expire, unless a user revokes your client's access to their account, or no API call has been made for 6 months.

Once your access token has expired, the Web API will respond with a `401 Unauthorized` error.

To refresh the token, make the following HTTP call:

#### URL

`https://api.athom.com/oauth2/token`

#### Headers

| Name            | Value                                           |
| --------------- | ----------------------------------------------- |
| `Content-Type`  | `application/x-www-form-urlencoded`             |
| `Authorization` | `Basic base64(Client ID + ':' + Client Secret)` |

#### Body

| Name            | Value                                        |
| --------------- | -------------------------------------------- |
| `grant_type`    | `refresh_token`                              |
| `refresh_token` | The `refresh_token` you retrieved in Step 2. |

For example, the HTTP request should look like this:

```http
POST /oauth2/token HTTP/1.1
Authorization: Basic ZXhhbXBsZTpleGFtcGxl
Content-Type: application/x-www-form-urlencoded
Host: api.athom.com
Connection: close
Content-Length: 56

grant_type=refresh_token&refresh_token=abc... 
```

When successful, the result will be a JSON-encoded object that looks like this:

```json
{
  "token_type": "bearer",
  "grant_type": "authorization_code",
  "access_token": "abc...",
  "refresh_token": "abc...",
  "expires_in": "3660"
}
```

Make sure to save the entire new token, and not only the new access token, because the refresh token might have also changed.

## Authenticating with Homey

Once you have authenticated with Athom Cloud API, you can view a user's information and their Homeys. But before you can communicate with a Homey itself, such as list devices and start Flows, you need to create a session on that Homey.

### Step 1 — Get a user's Homeys

First, you can get a list of a user's information and their Homeys.

```http
GET https://api.athom.com/user/me
Authorization: Bearer <access token>
```

This will return a JSON object, for example:

```json
{
  "_id": "688770a242d4006cf3cf0216",
  "email": "john@doe.com",
  "firstname": "John",
  "lastname": "Doe",
  "homeys": [
    {
      "_id": "688770c8189ccd274b5a8bfe",
      "name": "John's Homey Pro",
      "platform": "local", // can be either 'local' for Homey Pro, or 'cloud' for Homey Cloud
      "localUrl": "http://192.168.1.100",
      "localUrlSecure": "https://192-168-1-100.homey.homeylocal.com",
      "remoteUrl": "https://688770a242d4006cf3cf0216.homey.eu-west-1.homeypro.net",
      // ...
    }
  ],
  // ...
}
```

Depending on whether your integration lives in the user's LAN network or in the cloud, choose `localUrlSecure` , `localUrl` or `remoteUrl` respectively. When you have the option of connecting locally, always prefer `localUrlSecure` over `localUrl` over `remoteUrl` in that order for speed & security.

{% hint style="info" %}
All of these URLs can change over time, and become `null`. You can cache them, but never rely solely on them. Make the `GET /user/me` again to get the latest URLs.
{% endhint %}

### Step 2 — Obtain a Delegation Token

Second, you need to create a delegation token. This is a JSON Web Token (JWT) with the `homey` audience. This will let Homey know that you have delegated access to that Homey.

```http
POST https://api.athom.com/delegation/token?audience=homey
Authorization: Bearer <access token>
```

This will return a JSON string, e.g. `"abc..."` in the body. This is your delegation token.

### Step 3 — Creating a Session on Homey

Finally, make a HTTP request to the user's Homey:

```http
POST https://688770a242d4006cf3cf0216.homey.eu-west-1.homeypro.net/api/manager/users/login
Content-Type: application/json

{
  "token": "<delegation token>"
}
```

This will return a JSON string, which is the session token *for this Homey*. For example, `"abc..."`. You can use this string when making API calls to this Homey.

Once this session expires, Homey will reply with a  `401 Unauthorized` status code.

### Step 4 — Making API calls to Homey

You are now ready to make API calls to Homey!

For example, to get a list of devices (if your Client has the `devices.readonly` scope).

```http
GET https://688770a242d4006cf3cf0216.homey.eu-west-1.homeypro.net/api/managewr/devices/device
Authorization: Bearer <session token>
```

This will return a JSON list of devices:

```json
{
  "abc...": {
    "id": "abc...",
    "name": "Kitchen Light",
    "class": "light",
    "capabilities": ["onoff", "dim"],
    // ...
  }
}
```

***

Now head over to the Web API Reference for [Homey Cloud](https://athombv.github.io/node-homey-api/HomeyAPIV3Cloud.html) & [Homey Pro](https://athombv.github.io/node-homey-api/HomeyAPIV3Local.html) to further develop your app. If you're interested in receiving realtime events, head over to [Socket.io Specification](/http-and-socket.io/socket.io-specification).


# Socket.io Specification

Once you've got the [HTTP Specification](/http-and-socket.io/http-specification) set up, you might be interested in receiving realtime events from Homey. For example, to do something when a device turns on.

While Socket.io is primarily developed for Node.js, there are many alternative clients available for other languages. Here are a few examples.

* [Python](https://python-socketio.readthedocs.io/en/latest/client.html)
* [Go](https://pkg.go.dev/github.com/zhouhui8915/go-socket.io-client)
* [Rust](https://github.com/1c3t3a/rust-socketio)
* [C#](https://github.com/doghappy/socket.io-client-csharp)

### Step 1 — Connect to Socket.io

Connect to the `localUrl`, `localUrlSecure` or `remoteUrl` of Homey Pro or Homey Cloud with only the `websocket` transport. We recommend using a `pingTimeout` of `8000ms` and `pingInterval` of `5000ms`.

### Step 2 — Authenticate with Homey

Emit an event `handshakeClient` with the following object as parameter:

```json
{
  "token": "<session token>", // The Session Token
  "homeyId": "abc..." // The ID of the Homey
}
```

As third and last parameter, provide a `callback` function with a two parameters `(error, result)` . If `error` is present, it could be a `string` with an error message or an object with the `error` and `error_description` properties.

If `result` is set, authentication was successful. Within `result`, there is a property called `namespace` , for example `/api`. This is the root namespace for Socket.io where broadcasts happen. Your client should again connect to this namespace.

### Step 3 — Subscribe to Events

To subscribe to realtime events, you need to let Homey know you are interested in these events. To do so, emit a `subscribe` event with an `uri` as second parameter. As third parameter, provide a `callback` method with an `(error, result)` pattern.

An URI could be, for example, `homey:manager:flow` to get events when a Flow gets created, updated and deleted. Another example is `homey:device:abc...` to get capability updates of a specific device.

After subscribing, bind a local event listener where the event name is the `uri`. For example, in JavaScript, this looks like `socket.on(uri, (event, data) { ... })` .

{% hint style="info" %}
To unsubscribe, emit the `unsubscribe` event with `uri` as second parameter.
{% endhint %}

Within the API reference, you can find all events that could be emitted. For example, see [ManagerFlow](https://athombv.github.io/node-homey-api/HomeyAPIV3Local.ManagerFlow.html#section-events).


