Tado authentication

after deleting the tado addon, stop OH and delete in this folder \\OPENHABIAN\openHAB-userdata\jsondb\StorageHandler.For.OAuthClientService.json all tado:home entries, start OH again and install also tado addon again, everything is working fine :slight_smile:

1 Like

Is there a dedicated topic for the tado binding?

Anyway, I (and undoubtedly many others) received this e-mail:

Sounds like a sophism…

There’s talk of a local API, but since OAuth was introduced lately, I wonder which API the binding uses?

Other discussions about this topic:

  1. Reddit - The heart of the internet
  2. Upcoming changes to the tado° API · Issue #151223 · home-assistant/core · GitHub

Apparently they mean the homekit API. But openhab never implemented that as far as I know.

Hi,

my tado bridge thing went offline yesterday evening. Testing the authentication with http(s)://:/tado I still get: “Status: authenicated”

Cancelling and rediscovering of the bridge didn’t help. Neither restarting OH. I am running version 4.3.5. Any hints what I can do?

Idem here… I wonder whether they went through with the limit already?

I’ll put the log level to TRACE and provide some logs later today.


Here they are:

I disabled my tado:home thing, and then re-enabled it. In the “normal” logs, this was the output:

10:02:48.637 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'tado:home:192_168_1_70' changed from UNINITIALIZED to UNINITIALIZED (DISABLED)
10:02:53.663 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'tado:home:192_168_1_70' changed from UNINITIALIZED (DISABLED) to INITIALIZING
10:02:53.714 [INFO ] [hab.event.ThingStatusInfoChangedEvent] - Thing 'tado:home:192_168_1_70' changed from INITIALIZING to OFFLINE (CONFIGURATION_PENDING): Try authenticating at http(s)://<YOUROPENHAB>:<YOURPORT>/tado?user=

The binding dedicated log (at TRACE level) gave this meager output:

2025-09-16 10:02:48.636 [DEBUG] [ernal.discovery.TadoDiscoveryService] - Stop Tado background discovery
2025-09-16 10:02:53.661 [DEBUG] [ernal.discovery.TadoDiscoveryService] - Start Tado background discovery
2025-09-16 10:02:53.661 [DEBUG] [ernal.discovery.TadoDiscoveryService] - Start Scan
2025-09-16 10:02:53.668 [TRACE] [ado.internal.handler.TadoHomeHandler] - initialize() api v2 created
2025-09-16 10:02:53.713 [DEBUG] [ado.internal.handler.TadoHomeHandler] - Error accessing tado server: Operation showUser failed with error 429

But when I log to tado’s website, there’s no problem. If I then copy a HTTP call, and make it in PowerShell, that’s also no problem:

PS C:\Users\Erik> Invoke-WebRequest -UseBasicParsing -Uri "https://my.tado.com/api/v2/homes/[myzone]/zones/2/schedule/activeTimetable?ngsw-bypass=true" `
>> -Method "PUT" `
>> -WebSession $session `
>> -Headers @{
>>   "authorization"="Bearer [mytoken]"
>> } `
>> -ContentType "application/json" `
>> -Body "{`"id`":2}"

StatusCode        : 200
StatusDescription : OK
Content           : {"id":2,"type":"SEVEN_DAY"}
RawContent        : HTTP/1.1 200 OK
                    Date: Tue, 16 Sep 2025 07:58:58 GMT
                    Transfer-Encoding: chunked
                    Connection: keep-alive
                    Vary: origin
                    Vary: access-control-request-method
                    Vary: access-control-request-headers
                    Vary:…
Headers           : {[Date, System.String[]], [Transfer-Encoding, System.String[]], [Connection, System.String[]], [Vary, System.String[]]…}
Images            : {}
InputFields       : {}
Links             : {}
RawContentLength  : 27
RelationLink      : {}

Maybe I should try deleting the tado:home entries in StorageHandler.For.OAuthClientService.json as mentioned here? But maybe you want me to do some other stuff for debugging purposes, @AndrewFG?

PS: For some reason, I have two tado:home things:


&

Tado was the first thing I ever installed, so I didn’t know what I was doing at the time. But I still don’t understand how this is possible (and workable)… Should I delete one of both tado:home things?

Its broken already for me too. I tried deleting the old credentials, but that makes no difference.

Bizarre, since you should have the “lifetime for free” version, no?

Anyway, if I log in via the site, I see this:

Copied for cURL (bash), that gives:

curl 'https://login.tado.com/oauth2/token?ngsw-bypass=true' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'accept-language: nl,en-US;q=0.9,en;q=0.8,de;q=0.7' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'origin: https://app.tado.com' \
  -H 'priority: u=1, i' \
  -H 'referer: https://app.tado.com/' \
  -H 'sec-ch-ua: "Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "Windows"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-site' \
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36' \
  --data-raw 'client_id=af44f89e-ae86-4ebe-905f-6bf759cf6473&grant_type=authorization_code&scope=home.user%20offline_access&code=[thislookssensitive]&redirect_uri=https://app.tado.com/nl/auth/authorize'

The response (copied from Chromes console) is this:

{
    "access_token": "[thisisprobablysensitive]",
    "expires_in": 599,
    "refresh_token": "[thisisprobablysensitive]",
    "refresh_token_id": "[thisisprobablysensitive]",
    "scope": "home.user offline_access",
    "token_type": "Bearer",
    "userId": "[thismightbesensitive]"
}

Maybe that refresh_token is something worthwhile?

But it (of course) seems more complicated than that: Upcoming changes to the tado° API · Issue #151223 · home-assistant/core · GitHub & Upcoming changes to the tado° API · Issue #151223 · home-assistant/core · GitHub.

2025-09-16 10:02:53.713 [DEBUG] [ado.internal.handler.TadoHomeHandler] - Error accessing tado server: Operation showUser failed with error 429

I don’t think the problem is with the token. Actually the above message explains it. HTTP 429 means “too many requests”…

Haha, we’re having the same conversation on two platforms. But for future reference:

I know, but the web app doesn’t respond 429; it responds 200. That means that it authenticates ‘differently’. Maybe its refresh token might give us the possibility to log in in a way that tado thinks the HTTP calls come from its web app. And then there is no 100 call limit.

I do have “auto-assist” and thus should have a 20’000 requests/day allowance. I am quite certain to remain consistently below this limit.

I would file a complaint then…

If they explicitly state that those who pay, may keep on using the cloud API, you shouldn’t get 429.

Actually, I just checked from work via openhab Cloud and bang, tado is back. When I left this morning at 8:30 is was still out of service.

Maybe it reset recently. Check again in a few hours.

The 429 comes from their server, it doesn’t have to do with the binding. The reason it still works from other software is probably that they throttle per User-Agent or only throttle home automation software, for example.

Don’t count on any such hacks working for long. As said, I’d bet it’s the User-Agent. And, the binding could “fake” the User-Agent used by the app or something else. But, I very much doubt they’d leave that open, since they want to force people to pay to use their API for home automation.

429 can also mean that they have added a rate limiter as well, so it could simply be that OH sends to many requests too rapidly. The binding might need to space requests apart a certain number of milliseconds or something like that.

My tado things are online now as well, so I think it reset. I expect them to go offline again shortly.

There could also be some “hiccups” as they try to roll this out…

I don’t doubt you’re right, but how is a browser different from any other client? Would it theoretically not be possible to “extract” the call that “works” in the browser, and make the same call via another client?

That depends on how thorough they are. If they use the browser’s JavaScript to make checks, they can do a lot of checks that OH’s client can’t handle.

I’m not saying that you can’t find ways to get away with such “hacks” for a little while, but when many people use it (like is the case with an OH binding), they will discover and counter it.

But, firstly, be sure what is triggering the 429. It’s easy enough to tweak the binding so that you can change the User-Agent (from code, not UI). See if that makes a change. Also try to analyze requests/second and see if that could be a part of the picture.

This is the code which fails with the 429 error at line #280. There seems nothing particularly odd about it (except perhaps for the rather odd user-agent header)..