Security & architecture
How the privacy promise is actually built.
Pulse claims your raw health measurements never leave your phone. That is a strong claim and a narrow one, so this page says exactly what it covers, what does leave the phone anyway, which keys live where, what our servers hold, what we and Apple can still read, and how you can check any of it yourself.
The claim, stated precisely
Your heart rate, heart rate variability, sleep and movement are read from Apple Health on your iPhone, interpreted on that iPhone against your own rolling baseline, and turned into one sentence. No measurement, no score, no chart and no history reaches our servers, because there is no code path that would send one. The sentence itself does travel: it is written for your partner, it is derived from your health data, and it reaches them through your shared iCloud space. That difference is the whole subject of this page.
That is a narrower promise than "we are private", and it is the one worth checking. The rest of this page is the checking.
Four things that follow from it
- We cannot show you your own health history from a web dashboard, because we do not have it.
- We cannot recover your chat if you lose your key and every device, because the key was never ours.
- We cannot build cloud features over your content, because our servers cannot read it.
- A subpoena served on us reaches operational records rather than health records: pseudonymous identifiers, push tokens, notification settings, short-lived server logs and anything you sent us yourself. It cannot reach a measurement or the readable text of an encrypted message, because we hold neither.
The route a day takes
Five steps. The first three happen on your phone, the fourth is the only one that crosses to anyone, and the fifth is the one answer that can come back.
-
01
Measured
Your Apple Watch, or a WHOOP band once that support ships, writes measurements into Apple Health on your iPhone. Apple Health is a database on your phone, not a service of ours.
-
02
Read, with permission
Pulse reads the types you allowed in the iOS Health permission screen, and only those. Revoke one there and the app keeps working with what is left.
-
03
Interpreted on the device
Today is compared against your own recent weeks by code running on your iPhone. There is no server in this step and no model anywhere in it.
-
04
One sentence crosses
The resulting cue, a coarse mood label and the display name you chose sync to your partner through iCloud, in a zone shared with exactly one person. Your name and photo are end-to-end encrypted. The cue and the mood label are not, so Apple can read them where they sit.
-
05
One answer can come back
The next morning the person the cue was about can answer whether how their partner showed up helped, by picking one of four fixed options. Only that option crosses back, through the same shared zone, with no measurement and no free text behind it.
Every piece of data, and where it sits
Three lists: what stays on your device, what crosses into the space you share with your partner, and what our application stores. Each entry says what protects it, and where that protection stops.
On your device, and not on our servers
Held in the iOS Keychain, readable only after the phone has been unlocked once since boot. The health rows are deliberately kept out of your iCloud backup. Your chat key is the exception that syncs, through your iCloud Keychain, so your own other devices can use it.
-
Heart rate, resting heart rate, HRV, sleep, steps, exercise and stand time, respiratory rate, blood oxygen, mindful sessions
Read from Apple Health. A rolling 90-day history stays on the phone so the app can draw a trend.
-
Menstrual cycle data
Read only if you turn on Cycle-aware support (Rhythm Awareness), which is off by default; without it, your cue is computed with no cycle input at all. iCloud mirroring is disabled for it in code, so the log itself never syncs, and symptoms and notes never leave the device at all. The phase leaves only if you additionally turn on the separate period and cycle calendar switch, which has its own row in the table below.
-
Unusual heart-signal windows
Noticed on the device. Nothing is shared until you approve that individual moment, and a filter strips numbers and cycle vocabulary from the wording before anything can leave. Workouts and active energy are read only to leave exercise out of these checks, and Pulse asks at most three times a day.
-
Your chat identity private key
Generated on your device, stored in your iCloud Keychain so your own other devices can use it. Never uploaded to us.
-
WHOOP access and refresh tokens
Only if you connect a band, which needs WHOOP support to ship first. Kept in the app keychain, marked device-only so they never sync, and revoked with WHOOP on disconnect.
-
Your consent record, and the app's own notification list
A versioned, timestamped record of what you agreed to, withdrawable at any time. Withdrawing stops all health processing immediately.
What crosses to your partner
Through your own iCloud, in a private zone shared with one named participant. The zone is not public: a link to it is useless to anyone whose iCloud identity is not on the participant list.
| What | Protection |
|---|---|
| The daily cue, its suggested actions, a coarse mood label, your display name and photo, and your local time if you share it, with a live “likely asleep” status; when your switches hold a reading back, a neutral “nothing new to share” cue in its place | Shared iCloud zone, read-only for your partner. Your name, photo and local time are end-to-end encrypted. The cue and the mood label are health-derived and are not, so Apple can read them. Cues expire at the end of the day. The sleep status lives one hour and is not end-to-end encrypted either. |
| Chat messages, photos, GIFs, voice messages, gestures, requests, Our Story entries, calendar events, the shopping list, shared notes, answers to the daily question | End-to-end encrypted on your device. Neither we nor Apple can read them. |
| Watchlist and wishlist entries: a title, a kind, a link, a cover, a status, and for a wish saved from a real place its address and map position; plus the day you count from | Plain inside your shared zone, so Apple can read them. Never health data. Comments, reactions and each partner's verdict are end-to-end encrypted. |
| The daily question and both answers | Each answer is end-to-end encrypted on your device like a chat message; only the day it belongs to is readable. They clear out of the shared space within 48 hours. |
| Typing markers, read receipts and the "hold, together" signal | Relayed live while the chat is open, stored nowhere. The hold signal is a single yes or no with no content at all. |
| Your period and cycle calendar, if you turn that switch on: the current phase, this period’s days, the days predicted for the next one, and the ovulation window | Plain inside your shared zone, so Apple can read it. This is the one row in this table that is health data, which is why the switch is separate from every other one, off by default, and clears the calendar from your partner’s device the moment you turn it off. Symptoms and the notes you log never travel. |
What Apple can read here, and what it cannot
Your shared space is a zone inside iCloud, so Apple stores everything in the table above. Chat, photos, GIFs, voice messages, gestures, requests, Our Story, calendar events, Know Us entries, Unsaid notes you choose to send and what is said back about them, and the comments on a watchlist entry arrive there as ciphertext your phone produced, and Apple can open them no more than we can. The daily cue, the mood label beside it, the daily question with both answers, plain watchlist and wishlist entries, and a shared cycle calendar if you turned that switch on, are protected by the sharing rules on the zone rather than by that encryption, which means Apple is technically able to read them. That is the line between the two, and it is why this page never says that nobody can see anything.
What our application intentionally stores
The app has no account system, so there is no profile, no message archive and no health record on our side. What is listed below is what the application deliberately keeps. Ordinary operational traces, technical logs, queue records, the live relay state a chat needs while it is open, exist the way they do on any hosted service, and the last row says so rather than leaving you to assume they do not.
| Record | Why it exists | Kept until |
|---|---|---|
| A pseudonymous iCloud identifier, a push token, the platform, three notification on/off switches, and a fingerprint of the key only you and your partner hold; plus, only if you switch on announcement notifications, that choice and your app language | So a notification can be routed to the right phone. | You delete your account in the app, Google's or Apple's push service reports the token invalid, or your phone has not refreshed it for 180 days. |
| A contact-form message: your name, email, optional country and what you wrote | So a person can answer you. | The conversation ends. It is emailed to our inbox; only the topic is logged. |
| Website session cookie and CSRF token | So the site works. Strictly necessary, no analytics and no advertising cookie exists. | The browser session ends. |
| Administrator accounts for this website and a log of their sign-ins | So we can publish these pages. Unrelated to the app, which has no login. | The account is deleted. The sign-in log is kept for 12 months. |
| A feature idea sent from the features page: the title, your optional description, link, name and email | So a person can read it, answer you and keep track of what was already suggested. | You ask us to remove it, or the idea has been dealt with. |
| Live Activity push tokens, short-lived technical logs, and the relay state a chat needs while it is open | So a gesture can reach the Dynamic Island, so the site can be operated and abuse investigated, and so two open chats can talk in real time. | Tokens go when you turn the feature off, delete your account, or after 180 days without a refresh. Logs are deleted after 14 days. Relayed signals are never written down. |
| A crash report, only if you read it and tap Send: app and iOS version, device model, language, the last tab, technical details, and any note you add | So we can find the cause and fix it. It never carries an iCloud ID, a name, a health value or a message. | 90 days, then it is deleted automatically. |
| How many times each version of the app was opened: a daily total per build and per hour of the week, with no identifier and no row per phone | So we know which versions are still in use and when an old one can be retired. | Up to 13 months, then the daily totals are deleted automatically. |
| Only if you switch on “Help improve Pulse”: a daily list of anonymous counts (which screens and actions were used, how many times), added to a daily total | So we can see which parts of Pulse are used. No identifier, timestamp or content is sent, so a count cannot be tied back to you or taken out again. | Up to 13 months as daily totals. Turn the setting off and nothing more is sent. |
What is deliberately absent: any health value, any message text, any name from the app, any location, any advertising identifier. Pseudonymous identifiers are pseudonyms, not anonymity: a pair of them shows us that two accounts are linked, which is the metadata limit stated further down.
The encryption model
Named rather than gestured at, so it can be argued with.
- Key agreement
- Curve25519, through Apple's CryptoKit. Each partner generates an identity key pair on their own device and they agree on a shared secret directly. No key material passes through our servers at any point.
- Message encryption
- AES-GCM, through CryptoKit, which authenticates as well as encrypts: a modified ciphertext fails to open rather than decrypting into something else.
- Where the keys live
- Your private key sits in your iCloud Keychain, tied to your Apple ID and available to your own devices. We have no copy and no way to request one. Locally cached health readings sit in the device keychain under the device-only class, which keeps them out of your iCloud backup.
- Transport
- Encrypted payloads travel through Apple's CloudKit. While both of you have the chat open, the same already-encrypted bytes can also take a faster path over our own real-time relay. It signs and forwards, and stores nothing. A chat message's sealed bytes can also ride inside its push notification, through our server and Google's Firebase Cloud Messaging, so your partner's phone can open it before the app is opened; neither can read them, and our server does not keep them.
- Notifications
- The visible part of a push is content-free by design: a fixed title and body written by our server plus a type string, never the message. A chat push may also carry that message sealed, as described under Transport, which nobody between the two phones can open. A request for something private is never spelled out on a Lock Screen where someone standing beside you can read it.
- The WHOOP sign-in
- Your phone talks to WHOOP directly. Our server performs only the token exchange, because WHOOP requires a client secret and a secret shipped inside an app is readable by anyone who downloads it. Nothing from that exchange is stored: no token, no WHOOP user id, no row. The redirect lands on a domain this app has claimed through Associated Domains, so the authorisation code cannot be intercepted by another app on the device.
From the journal: What end-to-end encryption means for a couples app
Who else receives anything
Every recipient, with what each one actually gets. Several of these only exist for people who use a particular feature.
| Recipient | What they receive | When |
|---|---|---|
| Apple | Two kinds of thing inside your own iCloud: encrypted payloads Apple cannot open, and readable shared-zone records it can, which means your cue, the mood label, watchlist and wishlist entries, and the day you count from. Also push delivery. And, only when you use them, Apple Maps (the place searches you type, and the area you plan dates in) and the iTunes Search API (a watchlist title, when your phone looks up a cover). | Always. This is where your shared space lives. |
| Google (Firebase Cloud Messaging) | A push token and a content-free notification title, body and type; for a chat message, possibly that message too, sealed with end-to-end encryption Google cannot open. Firebase Crashlytics is linked as well, but only records a crash on your phone; it sends the report only if you tap Send when the app asks after a crash: a stack trace, the device model, the iOS version and a random installation identifier, never health data, message content or contact details. Firebase analytics and ads are disabled in the build. | When a notification is sent to you, and after a crash only if you tap Send. |
| GIPHY | Your GIF search terms. The GIF you actually send travels end-to-end encrypted like any message. | Only while you have the GIF picker open. Never open it and nothing is sent. |
| WHOOP | Your own sign-in and your own measurements, read by your phone directly from WHOOP. | Only if you connect a band, once that support ships. |
| Fastmail | The contact message you wrote us. | Only if you write to us. |
Verified absent from both codebases
- No analytics SDK of any kind
- No advertising or attribution SDK
- No advertising identifier, and no tracking permission prompt, because there is nothing to track
- No analytics, session-replay or attribution SDK. Crash reporting is the one diagnostic exception, and it is named in the table above rather than quietly left off this list. The two first-party counters in the table above are not SDKs, carry no identifier and send nothing to a third party.
- No payment or subscription processor
- No generative or language model writes or reads your words, in the app or on the server. The optional Translate action on a message uses Apple's built-in translation.
What this does not protect you from
The part most pages leave out, and the longest section here on purpose. None of the following is a bug report; all of it is either a deliberate trade or a known limit we would rather you heard from us than found out.
-
The daily cue is derived from your health data, and it does leave your phone
It has to. It is written for your partner. It travels inside your shared iCloud zone alongside the mood label, and it is not separately end-to-end encrypted the way chat is, so Apple is technically able to read it. We say this plainly because "interpreted on your device" is easy to hear as "nothing about your health ever leaves", and only the first of those is true. What does not travel is the measurement behind the sentence: no heart rate, no HRV, no sleep hours. The one health figure that can travel on its own is the cycle calendar, which is a separate switch, off by default, with its own row in the table above.
-
We can see metadata, and encryption does not remove it
We can see that an account exists, that two accounts are linked, that a message of a certain size moved between them at a certain time, and the token Apple needs to deliver a push. We keep as little as we can and sell none of it, but "we cannot read your messages" and "we know nothing about you" are different sentences, and only the first is true of anyone.
-
Copies in a calendar are outside the encryption
If you mirror your plans into a calendar, Pulse writes ordinary calendar entries: titles, times, places and notes, readable. A calendar that syncs to iCloud, Google or Outlook stores them with that service, and anyone you share it with can see them. Pulse asks before it writes to such a calendar, but once the copy is there, that calendar's rules apply, not ours. We state this plainly because the shared calendar itself is end-to-end encrypted, and a reader would otherwise reasonably assume the copy is too.
-
Some shared entries are plain, on purpose
Watchlist and wishlist entries, a title, a kind, a link, a status, and for a wish saved from a real place its address and map position, sync as plain records inside your shared zone, because they flow before the key exchange that protects chat. So does the day you count from. Apple can read them; they never contain health data. The comments and reactions on watchlist entries are encrypted.
-
Apple is underneath all of this
Your shared space is an iCloud zone, your keys sit in the iCloud Keychain, and your measurements live in Apple Health. The encrypted records are opaque to Apple exactly as they are to us. The rest of the shared zone is not, as the two rows above describe. Using Pulse means trusting Apple with that much, and an architecture that says otherwise would be describing a different app.
-
We do not claim forward secrecy
The chat key comes from a Curve25519 agreement between your two identity keys, not from the per-message ratchet a dedicated messenger uses. So we make no forward-secrecy claim: a private key taken off a device could open the messages it protected, rather than only the next one. We would rather name the limit than let the phrase "end-to-end encrypted" carry a property we have not built.
-
Your keys depend on your Apple account
Your private key lives in your iCloud Keychain so your own devices can reach it. That is what lets a new phone work without us ever holding a copy, and it is also a dependency: whoever controls your Apple account and can add a device to it is in a position we cannot help with, because there is no password of ours in the way. Keep two-factor authentication on that account.
-
Pairing leaves a brief public trace
While an invite is open, a record holding a pseudonymous iCloud identifier, your chosen display name and a short code is readable by other signed-in users of the app's iCloud container. Codes expire after 48 hours and the records are scrubbed on acceptance, on disconnect and on account deletion. The shared zone itself is not exposed this way: it is scoped to your partner's iCloud identity, so a harvested link opens nothing.
-
The notification endpoint is guarded by a key that ships in the app
That means it is not a real secret. The worst case is that someone could cause a content-free notification to appear on a phone whose pseudonymous identifier they already know; the endpoint returns a delivery count and discloses nothing about the person. It is rate-limited, and hardening it with per-device attestation is on the list rather than done.
-
Your own devices, and the people near them
Anyone who can unlock your phone can read your messages, which is true of every messaging app. Turn on the in-app Face ID lock if that matters to you. Equally, end-to-end encryption protects the wire, not the person you chose to send something to.
-
A partner is not always a safe person
Pulse is built for two people who chose each other, and nothing in it can tell the difference between a partner who is worried about you and one who is controlling you. If someone is pressing you to install it, to turn sharing back on, or to hand over your phone, that is not a problem encryption solves. Pause and disconnect are one tap away, pausing can be invisible, and you never owe anyone an explanation for using either.
-
Pausing stops what comes next, not what already arrived
Pause stops anything new from crossing, and can do it without telling your partner. It does not reach backwards: a cue or a message that already arrived is on their device, and no button of ours can take it back. Ending the connection removes the shared records for the same reason it cannot empty their phone. This is how every messenger behaves, and it is worth knowing before the day you need it.
-
No independent audit yet
The review this page is built from was done by us, against our own code, on the dates listed below. That is more than an intention and less than an external audit, and calling it anything else would be the first dishonest sentence on the page. An independent review is something we intend to commission, and we will date it here when it happens.
-
A connection can end without either of you ending it
Pulse watches for your partner's shared space, because an explicit goodbye can be missed: they may end things while your phone is offline, and without this check a device would sit "connected" to nobody forever. So a shared space that stays unreachable is eventually treated as a connection that ended, keeping your data. We are naming it here because it is a decision the app makes on your behalf, and because we got it badly wrong once: an earlier version acted after three checks, about a minute, and since ending it on one phone removes what the other phone is watching for, a brief outage could disconnect both people within minutes of each other. It now takes seven continuous days, a single sighting resets the clock, and anything the app cannot determine, being offline among it, is not counted at all.
How to check this yourself
You should not have to take our word for it, and on iOS you largely do not have to.
-
01
Turn on App Privacy Report
In iOS Settings, under Privacy & Security, App Privacy Report records which domains each app contacts and which sensors it touches. Use Pulse for a week and read what it lists. You are looking for the absence of analytics and advertising domains.
-
02
Read the Health permission screen
Settings, then Health, then Data Access & Devices, then Pulse. It shows every type the app can read and write. Revoke anything there and watch the app keep working with less.
-
03
Check the App Store privacy label
Apple requires the label to match the code, and ours declares a name, a pseudonymous user identifier and a device token, all marked as app functionality, none marked as tracking.
-
04
Watch the traffic yourself
If you are the sort of person who owns a proxy, point one at the app. What you will see is iCloud, our push endpoint, our relay while a chat is open, GIPHY if you open the GIF picker, Apple Maps when you search for a place, Apple's iTunes search when the watchlist looks up a cover, and WHOOP if you connected a band. What you will not see is a measurement.
-
05
Ask us something specific
Vague privacy questions get vague answers everywhere. A specific one about a particular flow gets a specific answer from us, and if the answer is uncomfortable it still gets answered.
When this was last checked
Each entry is either a review of the shipped code against what this site and the policy claim, or a correction to those claims, with what was found and changed.
-
2 July 2026
Full review of both repositories. Found and fixed: an undisclosed recipient list, a "we store nothing" claim that was untrue of the push record, and an account deletion that did not remove that record. The App Store privacy label was corrected at the same time.
-
24 July 2026
Reviewed the real-time relay and two new features. Disclosed the relay as an additional transmission path, and stated plainly that the daily question is not end-to-end encrypted like chat.
-
29 August 2026
Reviewed the shared watchlist and the WHOOP import. Added WHOOP as a named recipient for the people who connect a band, and documented that link previews and cover art are fetched by the sender's device only.
-
13 September 2026
A copy review of the whole website rather than a new review of the code, so the date above is unchanged. Corrected claims that had grown broader than the architecture: the daily cue described as though it stayed on the device, the daily question described on the features page as end-to-end encrypted like chat, a server inventory called complete that omitted feature ideas and Live Activity tokens, and a subpoena answer that implied we hold nothing at all. Made Apple's view of the shared zone explicit, and added the forward-secrecy, Apple-account, coercion and pause limits below.
Found something?
Responsible disclosure is welcomed and credited. Write to [email protected] with enough detail to reproduce, and give us a reasonable window before publishing. We do not run a paid bounty, we are too small for that to be honest, but we will not send a lawyer at you either.
Read the rest of it.
The privacy policy carries the legal version of everything above, including your rights and how to exercise them.