-
-
Notifications
You must be signed in to change notification settings - Fork 1
API Rate Limits EN
Sprache: English · Deutsch
The Husqvarna APIs (both Gardena Smart System and Automower Connect) have a monthly request quota of approximately 10,000 requests/month per application. This page describes how the integration stays within those limits and what happens when they are exceeded.
Each API has its own independent budget. Using one does not affect the other. Both APIs share the same OAuth token endpoint, but token requests do not count against the per-API quota.
Both APIs use the same architecture: real-time WebSocket push with REST polling fallback. Each API maintains its own connection.
Startup (every HA restart or integration reload):
| # | API Call | Purpose |
|---|---|---|
| 1 | POST /oauth2/token |
Acquire an OAuth2 access token |
| 2 | GET /locations/{id} |
Fetch all devices and their current state |
| 3 | POST /websocket |
Request a WebSocket URL for real-time updates |
| 4 | WebSocket connect | Open the persistent connection for push updates |
That is 3 REST calls + 1 WebSocket connection per startup.
Normal operation (WebSocket connected):
| API Call | Frequency | Purpose |
|---|---|---|
GET /locations/{id} |
every 1 hour | Health-check poll — verifies device list, detects new devices |
POST /oauth2/token |
every ~55 minutes | Token refresh (separate endpoint, doesn't count against quota) |
| WebSocket messages | continuous (push) | All device state updates arrive here at zero REST cost |
Daily total: ~24 health-check polls/day — roughly 7 % of the monthly budget.
Fallback operation (WebSocket down):
| API Call | Frequency | Purpose |
|---|---|---|
GET /locations/{id} |
every 5 minutes | Poll for device state (matches Gardena sensor hardware update frequency) |
POST /oauth2/token |
every ~55 minutes | Token refresh |
Daily total: ~288 polls/day — roughly 86 % of the monthly budget.
Startup:
| # | API Call | Purpose |
|---|---|---|
| 1 | POST /oauth2/token |
Acquire an OAuth2 access token (shared auth) |
| 2 | GET /mowers |
Fetch all mowers and their current state |
| 3 | WebSocket connect | Open the persistent connection for push updates |
Normal operation (WebSocket connected):
| API Call | Frequency | Purpose |
|---|---|---|
GET /mowers |
every 1 hour | Health-check poll |
POST /oauth2/token |
every ~55 minutes | Token refresh |
| WebSocket messages | continuous (push) | All mower state updates |
Daily total: ~24 polls/day — roughly 7 % of the monthly budget.
Fallback operation (WebSocket down):
| API Call | Frequency | Purpose |
|---|---|---|
GET /mowers |
every 5 minutes | Poll for mower state |
POST /oauth2/token |
every ~55 minutes | Token refresh |
Daily total: ~288 polls/day — roughly 86 % of the monthly budget.
| API Call | Throttle | Purpose |
|---|---|---|
PUT /command/{id} (Gardena) |
token bucket — 10 tokens, refill 1 / 5 s | Valve, switch, mower commands |
POST /mowers/{id}/actions (Automower) |
token bucket — 10 tokens, refill 1 / 5 s | Mower actions (start, pause, park) |
PATCH /mowers/{id}/settings (Automower) |
token bucket — 10 tokens, refill 1 / 5 s | Cutting height, headlight, stay-out zones |
Each button press or automation action is one API call. The token bucket allows small bursts (e.g. opening several valves in a row) while capping the long-term steady-state rate at ≤1 command / 5 s.
| Strategy | Detail |
|---|---|
| WebSocket-first architecture | State updates arrive in real time via persistent WebSocket. REST polling is only a fallback. The outer reconnect loop attempts reconnection 3 times over ~20 minutes (60 s → 5 min → 15 min), each time fetching a fresh signed WS URL. A watchdog timer checks every 60 s that the WebSocket is still receiving data — if silent for 5 min, the connection is forcibly recycled. |
| Single-use WebSocket URLs | Husqvarna's signed WS URLs are single-use — once rejected (e.g. HTTP 410), retrying the same URL is pointless. Any failure is escalated immediately to the coordinator instead of burning bandwidth on the dead URL. A fresh URL is fetched on each new connect attempt. |
| WebSocket URL caching | Within a single connect attempt the freshly fetched URL is cached and reused while the auth token is still valid. The cache is invalidated when the token expires or a connect attempt fails. |
| Connect guard | An async lock prevents parallel WebSocket connect attempts (e.g. watchdog and poll cycle racing), avoiding duplicate API calls. |
| Circuit breaker | After 3 consecutive WebSocket start failures the integration enters a 15-minute cooldown during which no new WebSocket connection is attempted (REST polling continues). The cooldown escalates to 30 min after 5 failures and 60 min after 7+. A successful connection resets the counter. Auth errors bypass the circuit breaker and trigger reauth instead. |
| WS handshake kill-switch | After repeated 4xx handshake rejections (e.g. HTTP 410/403/429 — typical of a server-side blocked Application), the WebSocket subsystem is suspended for 1 hour and REST polling is also paused until a real device update confirms the stream is healthy. Prevents account-block scenarios from burning ~288 REST calls/day for nothing. A repair issue (husqvarna_application_blocked) points the user at rotating the Husqvarna application. The kill-switch state is persisted to disk (since 1.12.8) so it survives HA restarts and config-entry setup retries — the previous in-memory-only counter was reset on every retry, leaving the integration stuck in a 5-minute "fail → fresh coordinator → fail" loop that burned quota confirming the same block over and over. |
| Persistent application-block detector | When the rate-limit ladder fires ≥10 times AND no successful poll has happened in the last 24 hours (or no successful poll has ever happened with the current Application), the same husqvarna_application_blocked repair issue is raised — even without a WebSocket handshake denial. Symptom of a server-side block where REST and WS both keep returning 429/410; the only fix is to rotate the Application. The issue clears automatically after several consecutive successful polls. |
| WS session timer (since v2.0.5) | Husqvarna enforces a server-side 2-hour maximum on WebSocket sessions for load balancing. When the server sends a graceful CLOSE at the 2-hour mark, the library exits normally (no error), so _ws_connected would have silently stayed True. A one-shot timer (WS_MAX_SESSION_SECONDS = 6900 s, 1 h 55 min) is now scheduled each time a session is established. On expiry, _async_ws_session_expired() proactively disconnects and schedules a normal reconnect — no data gap, no stale state. The timer is cancelled on explicit error or shutdown. |
| Adaptive polling interval | When WebSocket is connected: 1-hour health-check only. When WebSocket drops: 5-minute polling (matches sensor hardware update rate). |
| Graduated rate-limit backoff | If any API call returns HTTP 429 — including token refresh and WS-URL requests — polling backs off exponentially (5 min → 10 → 20 → 40 → 60 min max) and resets after several consecutive successful responses. |
| Command throttling (token bucket) | 10 commands, refilling at 1 token per 5 s. Allows small bursts while keeping the long-term rate at ≤1 command / 5 s. |
| Auto-stop safety net | When the monthly API budget drops below 5 % remaining (fewer than 500 of the 10 000 requests), the coordinator pauses REST polls, WebSocket (re)connect attempts, and user-issued commands — the latter return a translated error (api_budget_exhausted). Normal operation resumes at the start of the next calendar month, or earlier if a new Husqvarna application is created. |
| Independent budgets | Both APIs have their own ~10 000 requests/month quota. Using one does not affect the other. |
- Don't restart Home Assistant frequently. Each restart triggers a full API poll and a new WebSocket connection.
- Avoid rapid-fire automations. If you have automations that send multiple commands in a loop, add delays between them. The integration enforces a 5-second minimum, but longer pauses are better for the quota.
- Use a dedicated API key for Home Assistant. The budget tracking sensors assume the full 10 000 requests/month are available exclusively for this integration. Sharing the same Husqvarna application credentials with another smart-home platform invalidates the budget percentage. Create a separate application on the Husqvarna Developer Portal for each system.
- Use one integration instance per API. Each additional instance adds its own polling and WebSocket overhead.
- Monitor for rate-limit warnings. Check Home Assistant logs for messages containing "Rate limited". The hub diagnostic sensor API budget remaining is also a good basis for alerting automations.
- The integration logs a warning (e.g.
Rate limited by Gardena API (hit #1), backing off to 0:05:00). - The polling interval increases with graduated backoff: 5 min → 10 min → 20 min → 40 min → 60 min (max).
- Existing entity states remain available (cached from the last successful update and WebSocket messages).
- Commands may fail until the rate limit resets.
- After several consecutive successful API responses the backoff counter resets and the normal polling interval is restored.
- If the monthly budget has been almost fully consumed (< 5 % remaining), the auto-stop safety net takes over: polls, WS reconnects, and commands are refused until the calendar month rolls over.
See also: Troubleshooting
English
- Installation
- Configuration
- Supported Devices
- Entities and Services
- API Rate Limits
- MQTT Bridge
- Automation Examples
- Limitations
- Troubleshooting
- Contributing
Deutsch
- Installation
- Konfiguration
- Unterstützte Geräte
- Entities und Services
- API-Rate-Limits
- MQTT-Bridge
- Automatisierungsbeispiele
- Einschränkungen
- Fehlerbehebung
- Mitwirken