Owner's guide

Device signals

Your phone or your Mac can report moments you were provably awake: a charger plugged in, a keyboard touched. Each report is one row in your database, and the morning sleep reading is built from those rows together with your own journal entries. This page says what a signal is, what the sleep reading does with one, how a device sends one, and what you see when a device stops.

What a signal isA signal is one row saying a device saw you awake at a moment

A device sends one request to your backend, and the backend stores one row in a device_signals table in your database: a kind such as charger or laptop, an optional label, and a timestamp. The kind is your own vocabulary. The backend accepts any name, so a new device can report itself without a release. A signal writes nothing into your journal. The sleep reading is the only thing that reads the rows, and it reads only the timestamps, so every kind counts the same: proof you were awake at that moment.

The sleep readingThe night is the longest qualifying quiet between two marks

Every 15 minutes the backend checks whether last night can be read, for each account whose Sleep reading switch is on under Settings → Sleep, and stops for the day once a reading is posted. A mark is any moment you provably left behind: every device signal from the last two days, whatever its kind, and every journal entry's time, except the sleep readings themselves. Writing a line in your journal is as good a proof of being awake as a charger is, so the reading works with no device feed at all.

The night is the longest gap between two consecutive marks that qualifies, never merely the first: a quiet stretch over dinner is not a night.

Length
At least 3 hours, at most 14. Gaps outside that range are passed over.
Where it starts
The gap's first mark falls at 7 PM or later, or before 5 AM. Bedtime is in the evening or the small hours.
Where it ends
The gap's last mark falls today, before 3 PM. A day whose first mark is later than that gets no entry.

The result posts once in your journal: Woke 9:00 AM · slept 12h 18m (from 8:42 PM). When the day's first mark is 11 AM or later, the waking was bounded rather than observed, and the entry reads Woke by 11:40 AM · slept under 13h 02m instead of stating hours nobody measured. A night you correct stays corrected: the detector skips any day that already has its entry. Last night's sleep, in the app guide, covers the correction itself.

The entry files under one life area, and under none until that area is set. Setting it is an operator's job today — POST /api/settings/sleep-area with the area's id — because no screen offers the choice yet. The detector stores the area rather than its name and reads the name as it writes, so renaming the area changes what tomorrow morning's entry says without touching anything here. Delete the area and the mornings go back to filing under nothing. The reading still posts. What time you woke is a fact about the night, and where the night belongs is a separate choice.

A signal's timestamp that names no time zone is read on your own clock, and one the reading cannot parse is skipped.

Sending a signalAny device that can make a web request can report

The request is a POST to /api/signal at your LifeOps address, with an Authorization header holding the word Bearer and a token, and a JSON body such as {"kind": "charger", "label": "bedside", "ts": "2026-08-09T21:42:00"}. The reply repeats the kind and the timestamp stored, so a test tells you it worked without opening the app.

kind
What happened, in your own word. Required.
label
Free words about the sender, stored beside the kind. Optional.
ts
When the thing happened, for a sender that only learns after the fact. Optional. A request without one is stamped the moment it arrives.
The token
A bearer token for your account, which decides whose database the row goes in. A wrong or missing one comes back 401 and stores nothing.

Settings mints a phone token and shows it once. The backend stores only its hash. Every token minted for your account keeps working when a new one is minted, so connecting a new device never breaks a feed on an older token.

Setting it up

Make a token for my device signals.Your Claude mints a bearer token for your account and shows it to you once. The backend stores only its hash, so nothing can print it back to you later.

When a device goes quietA stopped device shows up in the readings, not in an alert

The backend runs no check on how recently each device has reported, so a dead automation raises nothing. What changes is the reading: with your journal lines as the only marks, mornings post loose (slept under) or stop posting. The jobs endpoint shows when the sleep job itself last ran, so a healthy job with drifting readings points at a device rather than at the backend.

Checking it

My sleep reading has been loose all week.Your Claude reads the newest signal rows off the backend, names the kind that stopped arriving, and rebuilds that device's automation with you.