Rate limits and throttling
Request-rate limits
Section titled “Request-rate limits”| Endpoint | Limit | On exceed |
|---|---|---|
POST /auth/login and POST /oauth/authorize |
10 per minute per IP address, shared | 429, Retry-After: 60, Too many attempts, please try again later |
POST /user/refreshSite |
1 per minute per user | 429, Retry-After: 60, Too many requests, please try again later |
No other endpoint has a fixed request-rate limit.
Per-controller command throttle
Section titled “Per-controller command throttle”Every device endpoint that has to talk to the controller enters a per-controller pipeline:
-
Commands to one controller run one at a time, with at least 500 ms between any two commands and at least 2 seconds between two writes to
setPumpInfo,manualSetorsetPhSettings. -
At most 6 commands can be queued or in flight for one controller. Cold reads and the server’s own background cache refreshes count too;
scheduleInfoand an uncachedpumpInfoeach use two commands. A request that would exceed the budget is rejected immediately with429:{ "status": "FAILED", "message": "device busy: too many pending commands for device 02_53_4D_00_00_01" } -
When a controller fails to answer, the server starts a cool-down: 5 seconds after the first timeout, 10 after the second, and 60 seconds from the third consecutive timeout onward. During cool-down every command to that controller is rejected:
{ "status": "FAILED", "message": "device busy: device 02_53_4D_00_00_01 is cooling down after timeouts, retry after 10s" }Durations are written like
5s,10sor1m0s. A successful answer resets the streak, and background cache refreshes are paused while a controller is cooling down.
Cached reads are not affected: a read whose cached copy exists is served instantly even during cool-down. Only cold reads and writes enter the pipeline.
Recommended client behaviour
Section titled “Recommended client behaviour”- Keep one request in flight per controller. Serialise your own writes.
- Leave at least 2 seconds between writes to the same controller, whatever the endpoint.
- On a controller-busy
429, parseretry after Nsfrom the message when present, otherwise wait 5 seconds, then retry. - Poll reads no faster than every 30 seconds; the server refreshes cached reads in the background at that rate anyway.
- Prefer Device API v2 for controllers that support it. v2 state reads never touch the controller.

