Keys for logging onto and using the athom-api

I’m trying to acquire the keys for logging onto and using the athom-api. I’m trying to do the steps programmatically. Im meeting some resistance.

I’ve been using posts on a different thread. Especially posts 30 by @Niels and 47 by @Lammy which are comprehensive and inspiring. Thank you!

Using python:

import requests as rq
import json as json

# Step 1: Authentication. JWT with credentials.
url = ''
lgn = {'email':'##@##.##', 'password':'##'}
jwt =, data=lgn)

# Step 2: Authorization. Obtain a delegation code. The HTTP result should be a 302 (redirect)
# Step 2a: Using the client credentials
client_id = '5cbb504da1fc782009f52e46'
client_secret = 'gvhs0gebgir8vz8yo2l0jfb49u9xzzhrkuo1uvs8'
redirect_uri = ''

user_token = json.loads(jwt.text)['token']
url = f"{client_id}&redirect_uri={redirect_uri}&response_type=code&user_token={user_token}"
rsp = rq.get(url)

# Step 2b: Sending allaw access form
rescource = "resource.homey.##"
pos_of_csrf = rsp.text.find('input type="hidden" name="_csrf" value="') + 40
_csrf = rsp.text[pos_of_csrf:pos_of_csrf+36]  # _csrf is 36chars

form_data = f"resource={rescource}&_csrf={_csrf}&allow=Allow" 
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
rsp_with_device =, data=form_data, headers=headers)

code = rsp_with_device.url.split('=')[1]  # Code in the redirect-url

# Step 3: Get an access token
# -- To be continued --

Step 1 works fine.
Step 2 now works fine.
Step 3 Is unfinished.

Note: I’m updating this original post as I’m solving the issues I’m encountering. This is because the end goal is to be able to log onto the athom-api and I figure this is the best way to show my current progress when posting questions.

Hi Ragnar, the second step uses the GET method. Seems you do a POST.

1 Like

Ok. My bad there, Thanks!, but doing a get returns the html document for the authorization. Not a redirect to a delegation code. I’ll update the initial question to keep it on track for the topic “getting keys…”

Did you see my second post in [Unsupported] Homey v2 REST API?
In short, the returned html in step 2 contains a form, fill it and POST it. That will give you the 302 and the delegation code in the headers.

I saw this, and I have identified the _csrf and resource values, but couldnt figure out how to post them.

A curl example would be useful since I’m still quite rookie on the technical part :slight_smile:

I don’t use curl that often, so I would have to look up the details.
What you should do is:
Add this header: Content-Type: application/x-www-form-urlencoded
Put this in form fields:
client_id=[your client id]
client_secret=[your client secret]
code=[the delegation code]
and (with https) post it to:
That will give you the refresh_token and access_token in json.

With curl it should be something like:
curl -X POST 'Content-Type: application/x-www-form-urlencoded' -F 'client_secret=<your client secret>' -F 'client_secret=<your client secret>' -F 'grant_type=authorization_code' -F 'code=<the delegation code>' https://

-X tells curl to send X-Form data.
-F is followed by a form field
-H is followed by a header

Maybe I missed something with curl, but that shouldn’t be too hard to find.

Thanks! But the question still remains on how to programmatically reproduce what happens when I press “Allow”.

A form like "resource=resource.homey.###&_csrf=###&allow=Allow" seems to be posted to the url resulting in a 302 redirect to the url containing the code. But how is _csrf obtained? It has a short lifespan and is not the same as the one saved to the session cookie.

Have you done this? If so, how did you solve it?

@Lammy, Ive had some progress obtaining the code. By using the _csrf from the html, I was able to successfully post the form and receive the delegation code. Using python:

rescource = "resource.homey.###" 
pos_of_csrf = responds.text.find('input type="hidden" name="_csrf" value="') + 40
_csrf = rsp.text[pos_of_csrf:pos_of_csrf+36]
form_data = f"resource={rescource}&_csrf={_csrf}&allow=Allow"  
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
rsp_with_device =, data=form_data, headers=headers)

code = rsp_with_device.url.split('=')[1]

I’ll continue experimenting with this towards Thanks this far for the assist! Im sure Ill have some more questions as I continue on your steps in the other post.

Good work. The way to find these things is indeed to use the developer mode in your browser. Login manually with your browser and monitor the traffic. In some cases you may need to set a few breakpoints, for example when data is exchanged with Java, or when you browser follows a redirect.
If a certain step in your code doesn’t work, have a look at the returned body. Often it contains a JSON error explanation.
I still have to write code to parse ‘chunked bodies’. As long as I don’t get this intermittent form to post (say Step 2b) I have little incentive to do so :wink:.