Privacy policy
Effective . Whisker Sheet is made by AiluroTech (Chung Kang) in Houston, Texas. Write to us at support@whiskersheet.com.
The short version
- Your clients’ records live on your iPhone. Without an account, nothing about them is sent to us.
- With an account they sync through our server sealed: encrypted on your phone with a key that stays in your iCloud Keychain. We cannot read them, and neither can anyone who gets hold of our database.
- What the server keeps in a form we can read is short: who you are to Apple, when your devices sync, and your subscription. No email address and no name.
- No advertising, no analytics, no tracking. We sell nothing.
- Delete your account in the app and it is gone from our database at once, and from every backup within seven days. The one exception, a restore after a failure, is explained below.
What we cannot read
What you write about a client (the address, the codes, the cats, your notes) and the photos you add are sealed on your iPhone before they are sent. The key that seals them is made on your phone and kept in your iCloud Keychain, which Apple syncs between your own devices. It is never sent to us.
That has a cost, and the app says so when you sign in: if iCloud Keychain is off and you lose your phone, the records are gone. Nobody can recover them, us included.
A photo is made smaller and stripped of everything attached to it, where it was taken included, before it is sealed.
What the server keeps that we can read
Sealing a record leaves a few things on the outside. These are the ones that say something about you.
- Apple’s identifier for you with us, which is how you sign in, and a random identifier we give your account. We ask Apple for neither your name nor your email address, and hold neither.
- A short reference code, shown on your account screen, for you to quote if you write to support.
- A token from Apple, stored encrypted, used for one thing: withdrawing this app’s Sign in with Apple access when you delete your account.
- For each client and each photo: a random identifier, which client a photo belongs to (so how many photos a client has), its size, whether the client is active or archived, and when it was first stored, last changed and deleted.
- For each device you sign in on: when it signed in and when it last reached the server.
- If you subscribe: Apple’s identifier for the subscription, which plan it is, its status, when its period ends, and when we last checked it with Apple.
- Counts of recent requests, a minute at a time, to stop abuse. When you are not signed in, a count is kept under a scramble of your IP address that reads as nothing without a key our server holds, never under the address itself.
The whole list, column by column, is at the end of this page.
What we never collect
About you, the app and the server ask for nothing: no name, no email address and no phone number, and the app never asks for your location. What you write about your clients, their names, numbers and addresses included, goes into the sealed records, which we cannot read; the app reads your contacts only when you pick one to fill in a client. No advertising identifier, no analytics, and no crash reports of our own. The app contains no one else’s code. We do not sell personal information, we do not share it for anyone’s advertising, and we do not track you across other apps or websites.
Writing to us is the exception: a message you send holds whatever it holds. See “Mail you send us” below.
What the app hands to your iPhone
Some things leave the app because you ask them to, and go where your iPhone sends them, not to us. Tapping an address opens it in Apple Maps. Adding visits to your calendar puts them in the calendar you use, with door codes only if you choose that. Sharing or exporting a care sheet sends what you chose to where you chose. A photo you take in the app is not saved to your photo library.
Your iPhone’s own backup, to iCloud or to a computer, includes this app’s records as it includes any app’s. That is between you and Apple, and we never see it. Apple holds the keys to an iCloud backup unless you have turned on Advanced Data Protection.
Who else handles your data
- Apple. Sign in with Apple; your subscription, for which Apple takes the payment, so we never see a card; iCloud Keychain, which holds your key; and, where a law requires it, your age range.
- Laravel Cloud, our host, and Neon, its database service. They run the server and hold the database, in the United States.
-
Cloudflare stands in front of our server and sees the IP
address each request comes from. It sets two cookies of its own on the
server’s answers,
__cf_bmand_cfuvid, for its own protection against bots and abuse. The app does not keep them. - Vercel serves this website and sees the IP address of each visit.
- Namecheap holds our domain and forwards mail sent to our support address on to our mailbox. The mailbox is with a mail provider of its own, which holds what you send us.
None of them is given your records in a form it can read.
How long we keep it
- Your account and what it has synced: until you delete the account.
- A client you delete: its contents leave our database at once. A marker stays until the account is deleted, holding the record’s random identifier and when it was deleted, so your other devices delete it too.
- Backups: our database keeps a rolling seven days of its own history, so that a failure can be undone. Whatever you delete is gone from that, and from any other copy we hold, within seven days.
- If we ever restore from a backup: a restore is for a failure, and may never happen. If one does, accounts deleted since the backup come back with it. Before the restored database is used we delete them from it again, where we can still tell which they were. One we could not tell stays until its owner deletes it again. One we delete again leaves the restored database’s own history within seven days of the restore. A client you deleted comes back to the server too, and is deleted again the next time your phone syncs.
- Server logs: our host keeps them one day. They record requests and errors and may include your IP address. They name an account only by its random identifier or its reference code. Our database service keeps a log of its own errors, which can include a value from a request that failed; we have not yet been able to confirm how long it keeps it.
- Request counts: a count stops counting after its minute, and is removed the next time anyone signs in.
- Mail you send us: kept in our mailbox for as long as we need it to answer you. It holds the address you wrote from, the name your mail program gives, and whatever you tell us. Ask, and we will delete it.
Deleting your account
You delete your account in the app, under More, then Account. The account page has the steps, including what to do if you no longer have the phone. Apple confirms it is you first. We then ask Apple to withdraw this app’s Sign in with Apple access, and delete the account, its records, its photos, its sign-ins and its subscription record. If Apple cannot be reached, the account is deleted all the same and the app tells you how to remove the access yourself. The key leaves your iCloud Keychain and your other devices. Your clients stay on your phone unless you choose to erase them too.
Deleting your account does not cancel a subscription. Apple keeps billing until you cancel it in your Apple Account’s subscriptions, and Apple keeps its own record of the purchase, which includes the random identifier we gave your account.
What support can see
If you write to us with your reference code, we can see your subscription, how many active clients you have, and when you last synced. Never what is inside a client’s sheet. “I lost a door code” has no answer from our side.
Your age
Whisker Sheet is for people who look after cats for a living, and is not directed to children. Accounts are for adults. Where a law requires it, as Texas’s does, the app asks Apple for your age range. The answer is held only while the app is open, is used only to decide whether to offer an account, and is never sent to us. Without an account, everything else in the app works as it does for anyone.
This website
This site sets no cookies and runs no scripts. It has no analytics, and it loads nothing from anyone else: the fonts are served from here.
If you live in California or Delaware
We do not sell personal information or share it for advertising, and no one else collects information about what you do in the app or on this site over time. Because nothing here tracks you from one site to another, a Do Not Track signal from your browser has nothing to switch off, and you are treated the same with it as without it. We hold no profile of you to review or correct: the app and the server hold no name and no email address for you. What the server holds about your account is the list on this page.
Changes to this policy
When this policy changes we post the new one here, with its date, before it takes effect. If a change alters what we collect, store or share, we tell the App Store first where the law requires it, as Texas’s does.
Everything the server stores
Every table in our database and every column in it, but one: the table our framework keeps its own upgrade history in, which holds file names and nothing about anyone. Our own tests compare this list with the database, so it cannot quietly fall behind: a column added there fails them until it is named here.
| Column | What it holds |
|---|---|
id
|
A random identifier for your account. Apple also holds it, attached to a subscription you buy. |
apple_user_id
|
Apple’s identifier for you with us, the same in any app we make. It is how the server knows it is you when you sign in. |
support_ref
|
An eight-character code shown on your account screen, for you to quote to support. |
apple_refresh_token
|
A token from Apple, stored encrypted. Used only to withdraw Sign in with Apple when you delete the account. |
created_at
|
When the account was made. |
updated_at
|
When this row last changed. |
| Column | What it holds |
|---|---|
id
|
An internal row number. |
record_id
|
A random identifier your phone gave the record. |
user_id
|
Your account. |
blob
|
The sealed record. We cannot read it. |
tombstone_seal
|
For a client you deleted, a sealed note of when. We cannot read it. |
is_active
|
Whether the client is active or archived, which the free plan’s limit counts. |
device_updated_at
|
When your phone last changed the record. |
seq
|
A running number that tells your devices what they have not fetched yet. |
deleted_at
|
When a client you deleted was deleted. |
created_at
|
When the server first held the record. |
updated_at
|
When the server last wrote it. |
| Column | What it holds |
|---|---|
user_id
|
Your account. |
next_seq
|
The next running number to give one of your records. |
created_at
|
When your account first sent a record. |
updated_at
|
When it last sent one. |
| Column | What it holds |
|---|---|
id
|
Always 1. |
value
|
A random value that changes if we restore the database, so every phone knows to send its records again. |
changed_at
|
When it last changed. |
| Column | What it holds |
|---|---|
id
|
An internal row number. |
asset_id
|
A random identifier your phone gave the photo. |
user_id
|
Your account. |
record_id
|
The client record the photo belongs to, which shows how many photos a client has. |
blob
|
The sealed photo. We cannot read it. |
created_at
|
When the server first held the photo. |
updated_at
|
The same moment: a photo never changes once stored. |
| Column | What it holds |
|---|---|
id
|
An internal row number. |
user_id
|
Your account. |
original_transaction_id
|
Apple’s identifier for the subscription. |
product_id
|
Which plan: monthly or yearly. |
status
|
Active, in a grace period, being retried, expired, or revoked by Apple, as after a refund. |
expires_at
|
When the current period ends. |
revocation_date
|
When Apple refunded or revoked it, if it did. |
environment
|
Whether it is a real purchase or a test one. |
last_verified_at
|
When we last asked Apple about it. |
created_at
|
When the server first held the subscription. |
updated_at
|
When this row last changed. |
| Column | What it holds |
|---|---|
hash
|
A one-way scramble of a random value issued for one sign-in or one account deletion. |
expires_at
|
Ten minutes after it was issued. |
| Column | What it holds |
|---|---|
id
|
An internal row number. |
tokenable_type
|
Always the same value: it says the sign-in belongs to an account. |
tokenable_id
|
Your account. |
name
|
Always “ios”. |
token
|
A one-way scramble of that device’s sign-in token, never the token itself. |
abilities
|
Unused. |
last_used_at
|
When that device last reached the server. |
expires_at
|
Empty: a device stays signed in until you sign out or delete the account. |
created_at
|
When that device signed in. |
updated_at
|
When this row last changed. |
| Column | What it holds |
|---|---|
key
|
The name of a count of recent requests: under your account’s identifier when you are signed in, or, when you are not, under a scramble of your IP address that reads as nothing without a key our server holds. |
value
|
The count, and when its minute ends. Also Apple’s public keys for checking sign-ins. |
expiration
|
When the row stops counting. |
| Column | What it holds |
|---|---|
key
owner
expiration
|
Unused. Nothing uses this table, so it is empty. |
| Column | What it holds |
|---|---|
id
queue
payload
attempts
reserved_at
available_at
created_at
|
Unused. Nothing uses this table, so it is empty. |
| Column | What it holds |
|---|---|
id
name
total_jobs
pending_jobs
failed_jobs
failed_job_ids
options
cancelled_at
created_at
finished_at
|
Unused. Nothing uses this table, so it is empty. |
| Column | What it holds |
|---|---|
id
uuid
connection
queue
payload
exception
failed_at
|
Unused. Nothing uses this table, so it is empty. |