Lights and automations
Your smart home can follow a pool's light. Each time the light changes, ClearToSwim sends the new one to IFTTT, or to Home Assistant or your own server. Lights is part of ClearToSwim Pro.
Red and amber, never a promised green
A bulb at the pool is a second look at the light, never the only warning. ClearToSwim cannot see your bulb, so it never asks one to show green it cannot vouch for: with IFTTT there is no green at all, and a green sent to a web address comes with a time limit your automation should keep.
Connect IFTTT
IFTTT's Webhooks need an IFTTT Pro plan. Any color smart bulb that IFTTT can set will do.
- In ClearToSwim, open the pool's Lights and tap Connect IFTTT.
- Tap Open IFTTT, copy your key from IFTTT's Webhooks settings, paste it into Webhooks key and tap Save.
- Lights shows three events, each with its exact name. Tap a row to copy its name; Applet events shows them again later.
- In IFTTT, make one applet for each event: if Webhooks receives it, set your bulb to that light.
- Tap Send a test, which fires the event for the pool's light now.
The three events
cleartoswim_xxxxxx_red: the pool is closed, or reopening soon. Set the bulb red.cleartoswim_xxxxxx_amber: lightning in the caution ring. Set the bulb amber.cleartoswim_xxxxxx_off: everything else, which is the pool open, outside its hours, or ClearToSwim unable to vouch for the sky. Turn the bulb off.
The six letters and digits in place of xxxxxx belong to that pool on your
account. Each pool gets its own names, the same on any key and after any reconnect, so
copy them from the app rather than typing them from here.
There is no green event, on purpose. An open pool turns the bulb off, because a bulb ClearToSwim cannot see must never show green. IFTTT accepts an event whether or not an applet listens for it, and cannot let a green go when no message follows, so only red and amber mean anything, and a dark bulb is never a promise that the pool is open.
Each event carries three values an applet can use: Value1 is the pool's name, Value2 its stage, and Value3 the alert's title, or nothing. IFTTT does not promise to run events in the order they arrive, so each light is fired once more about two minutes later. Removing the automation sends IFTTT the off event, then stops.
Use a web address
For Home Assistant or your own server. Make a webhook there, then in ClearToSwim open the pool's Lights, tap Use a web address, paste the address and tap Save. Copy the signing key it shows you, which lets your server check that each message came from ClearToSwim, then tap Send a test. Lights shows the key only until you close it; after that, New key is the way to get one.
The address must:
- start with
https://, so every message is sent encrypted; - use the standard port, so no port such as
:8123on the end of the name; - be public, with a name that has a dot in it: an address that works only on your
home network, or a number such as
192.168.1.4, is refused; - carry no name or password before an
@, and run to at most 500 characters.
An IFTTT address is refused here: it would get every light, green included, and cannot let a green go. Use Connect IFTTT instead.
What is sent
Each time the pool's light changes, ClearToSwim sends a POST with a JSON
body. Redirects are not followed, your server has five seconds to answer, and any
2xx answer means it took the light. The body of the answer is not read. The
headers follow the Standard Webhooks specification, so its libraries can read them:
content-type: application/json
user-agent: ClearToSwim-Automations/1
webhook-id: msg_<24 letters and digits>
webhook-timestamp: <unix seconds of this attempt>
webhook-signature: v1,<base64 signature>
A closure, as your server receives it:
{"type":"pool.light","version":1,"id":"msg_...","sequence":1791234843,
"at":"2026-10-05T21:14:03Z","pool":{"id":"p1k9x","name":"Backyard"},
"stage":"closed","previousStage":"open","swimmable":false,
"lamps":{"red":true,"amber":"off","green":false},"color":"red",
"validForSeconds":null,
"message":{"title":"Backyard: Closed",
"body":"Lightning detected in the area. Evacuate Backyard and seek shelter."}}
type:pool.lightfor a change,pool.testfor Send a test,pool.removedfor the last message when the automation is removed (every lamp off), andpool.light.statefor the state link's answer.stage: always one of the seven below, never null.previousStage: the stage your server last took; null on its first message.sequence: rises with every message. Keep the highest you have seen and ignore anything lower.swimmable: true for open and caution; false for closed, reopening soon, after hours and before opening; null for checking.lamps: red and green are true or false, and amber isoff,steadyorblinking.coloris the answer for one bulb: red if red is lit, else green if green is (caution is green on one bulb), else amber (only before opening), else null.validForSeconds: 900 whenever green is lit, null for every other light.message: the push alert's own title and body when the change is one the alerts announce, otherwise null.
No message carries a reopening time or a countdown: a strike that restarts the wait would make a stated reopening time wrong, with no message to correct it.
The seven stages
open: green.caution: green and blinking amber; lightning in the caution ring, the pool still open.reopeningSoon: red and steady amber, the last minutes of the wait.closed: red.checking: every lamp dark; ClearToSwim cannot vouch for the sky right now.afterHours: every lamp dark, outside the pool's hours.beforeOpening: the time just before the pool's hours begin. Red if lightning is close, blinking amber alone if it is in the caution ring, otherwise dark.
A pool whose light shows no amber counts caution as open and reopening soon as closed, as its stoplight does.
Check the signature
The signed text is the webhook-id, the webhook-timestamp and
the raw body, joined by full stops: <id>.<timestamp>.<body>.
The signature is the base64 of its HMAC-SHA256, keyed by the 32 bytes your signing key
decodes to: drop the whsec_ at its start and base64-decode the rest. A
message that is tried again keeps its id and body and is stamped and signed afresh, so a
receiver may refuse an old timestamp; the Standard Webhooks libraries allow five
minutes.
The header can carry more than one signature, separated by a space. For 24 hours after you make a new key it carries two, one under the new key and one under the previous one. Check each and accept the message if any one verifies, as the libraries do. A server that compares the whole header with one signature refuses every message for those 24 hours.
A green has a time limit
While a green stands, ClearToSwim sends it again 10 minutes after your server took it,
as a new message. Each green is good for validForSeconds, 900 seconds, which
is 15 minutes. Treat a green you have not heard again within that time as checking and
turn the bulb off: in Home Assistant, a template or timer that turns the light off when
the last message is older than that. A red is sent once and stays until the next
message, so never let that timer turn off a red. A bulb that can only be switched on
each message keeps the last light it was sent until the next one arrives; read the
state link instead.
If your server misses one
A light your server did not take is tried again, with the same id, 30 seconds and 1, 2, 5
and 10 minutes after each failure, then every 10 minutes. A newer light replaces one
still waiting. A red, or any light that takes a green away, keeps being tried for as
long as it stands, so a server that was down gets the closure within 10 minutes of
answering again. A green is tried for up to an hour, and is held back if your server
refuses it. An answer of 410 stops the messages.
The state link
Right after you save the address or make a new key, and until you close Lights, Copy key shares the signing key, the state link and its key. Anything that polls can ask the state link for the light now, with the state link key as a bearer token:
GET <state link>
Authorization: Bearer rk_<32 letters and digits>
It answers the same body, typed pool.light.state, and answers
checking when ClearToSwim has not vouched for the light lately: within two
minutes of going quiet, and sooner for a green. Each key may read it at most 6 times a
minute.
A new key
New key makes a new signing key and a new state link key. Your server can keep checking messages with the key it has for 24 hours, so put the new key in before then. Anything that reads the state link needs the new state link key at once.
How long it runs
One account can connect up to ten pools. Lights keeps working while the app stays installed, even if you do not open it, and stops when you remove the automation, sign out or delete your account, and within about a month after you delete the app. Removing the automation sends your server one last message turning the light off, then stops.
Questions: support@cleartoswim.com.
ClearToSwim is an informational aid, not a safety guarantee. Always follow official warnings. If you see lightning or hear thunder, get out of the water and take shelter in a substantial building or a hard-topped vehicle. Wait until 30 minutes after the last thunder before returning to the water.