[Unsupported] Homey v2 REST API

Just noticed I didn’t mention the http headers.
These are the ones I use in all calls:

  • “Connection: keep-alive”
  • “Accept-Language: en-us”
  • “Accept-Encoding: br, gzip, deflate”
  • “Origin: anyname://authorize”
  • “Referer: anyname://authorize”
  • “User-Agent: Anyname/1.0”
    Add this header if you post form data: “Content-Type: application/x-www-form-urlencoded”
    And this header if you send JSON in the body: Content-Type: application/json
    Notice, I used a fake application url scheme for Origin and Referer.
1 Like

In what context do you use this authentication method, @Lammy? CLI/Web Page/Server Side API? If you are using JavaScript, could you share your code with us/me?

It is C/C++ code, running on armgnulinux. Too much to post it all here, but here is for example the function for step 1 (indentation is lost).

athomLogin

bool athomLogin(std::string email, std::string passw, std::string &jwt)
{
const char *headers =
“Accept: application/json\r\n”
“Accept-Language: en-us\r\n”
“Connection: keep-alive\r\n”
“Accept-Encoding: br, gzip, deflate\r\n”
“Origin: domos://authorize\r\n”
“Referer: domos://authorize\r\n”
“Content-Type: application/x-www-form-urlencoded\r\n”
“”;
bool res = false;
size_t sz = 512;
char buffer[sz], payload[sz];
https_handle_t hnd = httpsCreateHandle(“accounts.athom.com”, 443, headers);
sprintf(payload, “email=%s&password=%s”, urlencode(email).c_str(), urlencode(passw).c_str());
headers_t ret_headers;
if (200 == https(hnd, “”, “POST”, “/login”, payload, strlen(payload), buffer, &sz, &ret_headers))
{
//for (size_t i = 0; i < ret_headers.size(); i++)
//{
// printf("%s\n", ret_headers[i].c_str());
//}
json reply = json::parse(buffer);
//printf("%s\n", reply.dump(2).c_str());
jwt = reply[“token”];
res = true;
}
httpsDestroyHandle(hnd);
return res;
}

3 Likes

A great topic and I loved to see two methods explained for retrieving the bearer.
Unfortunate I was not able to retrieve the bearer in the last part on both methods.

I used the following curl command
curl -d {“token”:“XXXXXXX”} -H ‘Content Type: application/json’ -XPOST https://192.168.1.17/api/manager/users/login
–> The result was: curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

and

curl -d {“token”:“XXXXXXX”} -H ‘Content Type: application/json’ -XPOST https://YYYYYYY/api/manager/users/login
–>The result was nothing, not response at all. I needed to kill the process with ^C.

All earlier steps we executed well, I was able to find the right JWT token (XXX) generated and I’m pretty sure I have the right Cloud_ID (YYYY) aswell.

Can someone shine a little light on a solution direction?

I saw a small mistake in the header in the commands, after I changed them both it resulted in the curl (35) error with and SSLv3 handshake failure. Any thought on what could cause the problem?

You can’t use https in combination with the IP-address directly, you’ll need to use https://192-168-1-17.homey.homeylocal.com

Thanks for your response. I altered the curl command in :
curl -H ‘content-type: application/json’ -d {“token”:“xxxx”} -X POST “https://192-168-1-17.homey.homeylocal.com

Just to be sure, I created a new JWT token in xxxx

This is the response from Homey in HTML format:

Error
Cannot POST /

Any guidance?

Sorry for the confusion, you still need to add /api/manager/users/login after the scheme and hostname in the URL:
https://192-168-1-17.homey.homeylocal.com/api/manager/users/login

I altered the curl command as follows:
curl -H ‘content-type: application/json’ -d {“token”:“xxxxxxx”} -X POST “https://192-168-1-17.homey.homeylocal.com/api/manager/users/login

This is the response:
{“code”:400,“error”:“invalid_json”,“error_description”:“An unkown error has occured [invalid_json]”}

It should (probably, I don’t know how this API works) be this:

curl -H 'content-type: application/json' -d '{"token":"xxxxxxx"}' -X POST "https://192-168-1-17.homey.homeylocal.com/api/manager/users/login"

Note that I’m using simple quote and double-quote characters, not “smart quote” characters.

Thanks, it worked. Really appreciated your help, now let’s see how to build this in a nice javascript runtime environment.

Hi, can someone please show me/us some fully code how to use these RestAPI’s?
How do to the auth?

Can someone please share his examples?
Thank you so much.

Sorry to ask again here, can someone please show me how to use the REST API ?
How to login using the curl?

Thank you

Ropske,

I’ve created a very basic, very small, working (javascript) example and put it on GitHub:


Feel free to fork/clone and reuse.

There is also a readme.md on how to get things working.

I’ve used it myself to create an alternate dashboard (with temperatures from all of my temperature-sensors) and 1 graph of the temperatures of the latest 24 hours (in one graph so more user-friendly then insights)

Credits to homey.ink and robertklep for the examples / steps.

4 Likes

Did you change your client_id and client_secret on GitHub?
Ok hope so!

Homeyscript to regularly fetch a new valid bearer token for using the API
The following guide, describes a setup that automatically fetches an updated bearer token for usage with your homey API. It consists of two main parts:

  • A homeyscript that returns an updated bearer token as a return tag value
  • An example flow that runs the homeyscript regularly and stores an updated bearer token in a logic variable

I’ve only tested it for my own command. I’d be happy to learn if it works for others as well-

homey.solweb.no/advanced-api-usage/bearertoken

Hi Homey Devs and Friends
I created a nuget package and a sample app in C# on GitHub:
Homey .Net

I implemented so far the following commands:

  • Get device for id
  • Get all devices
  • Get devices for zone id
  • Get capability time log
  • Gel all zones
  • Get all flows
  • Get flow for flow id
  • Get all alarms
  • Update alarm
  • Get system info
  • Set boolean capability
  • Enable flow
  • Trigger flow

Feel free to have a look at the request or to contribute.
The login is not that comfortable. :face_with_raised_eyebrow:

Hi,

I tried your script but I got an error on line:
let code = response4.headers[’_headers’].location[0].split(’=’)[1]

I changed it to:
let code = body4.split(’=’)[1]

and removed line:
console.log(" Response from authorization. Redirect to ", response4.headers[’_headers’].location[0])

And now it works!

Very usefull! Thanks!

Hi Andreas,

I have tried your script and I get there error message mentioned by Ton_T (TypeError: Cannot read property ‘location’ of undefined).

I’ve also tried his suggested change which works but doesnt return anything (Response content {“code”:500,) → Returned: undefined

Any ideas?

Besides the changes 2 posts before, change
let rawd = raw[0].split(‘;’) on line 50 to let rawd = raw[2].split(‘;’)