From 288a660ef559484ec2a6187f45faf17079faf2b7 Mon Sep 17 00:00:00 2001 From: Fredrik Soderblom Date: Fri, 24 Jul 2026 10:03:45 +0200 Subject: [PATCH] Fix 403 on spa fetch by resolving the real spa ID get_profile() was using the account's own user "_id" as the spa ID, which is a different ID namespace. Fetching spa data with that ID returns 403 Forbidden even with valid credentials. Resolve the actual spa ID from the /spas list instead, as done prior to 272786e. --- spa_client.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/spa_client.py b/spa_client.py index 6db91fa..177adf0 100644 --- a/spa_client.py +++ b/spa_client.py @@ -45,17 +45,23 @@ def get_profile(self): "User-Agent": "Mozilla/5.0" } - # Fetch user profile to extract spa ID + # Fetch user profile (mainly to validate the token) response = self.session.get(PROFILE_URL, headers=headers) response.raise_for_status() - - # Extract spa ID from user profile - profile_data = response.json().get("data", {}) - user_data = profile_data.get("user", {}) - self.spa_id = user_data.get("_id") - + + # Fetch the actual spa ID from the spa list. The profile's user "_id" + # is the account ID, not the spa ID, and using it causes a 403 when + # fetching spa data. + spa_response = self.session.get("https://iot.controlmyspa.com/spas", headers=headers) + spa_response.raise_for_status() + + spas = spa_response.json().get("data", {}).get("spas", []) + if not spas: + raise ValueError("No spas found in account") + + self.spa_id = spas[0].get("_id") if not self.spa_id: - raise ValueError("Spa ID could not be extracted from profile response") + raise ValueError("Spa ID could not be extracted from spa list response") def fetch_spa_data(self):