Privacy
Short version: what you write about your child — their name, what helps them, your notes — is kept on our server, under an account tied to your email. We don't sell it. We don't show ads. No other company counts your visits here. Anyone holding a share link can read that card and pass it on, and we can't un-read it for you. When Koko's helper answers a question, or turns your words into Spanish, your words go to the company that runs the model. You can delete one child's Koko, or your whole account and everything under it, yourself — with one exception, and it is the only one: a line you choose to send to the Village stays on that public page, because nothing in it points back at you for a delete to follow.
This page describes Koko Says as it actually worked on 4 August 2026. If we start keeping something we don't keep today, we change this page first.
No lawyer has read this page. We wrote it ourselves, about the app we actually built.
Who we are
Koko Says is made by a family, not a company. We built it for our own son so the people who look after him know what helps in ten seconds. There are no investors and no staff. The site runs on Vercel, the database is at Neon, and sign-in emails go out through Resend. When something breaks, a scrubbed report of it goes to Sentry, the company that helps us find and fix errors — what gets scrubbed out first is spelled out further down, in the error table section. The language models we use are reached through Vercel's AI Gateway, which hands the text on to the company whose model it is — today that is Google, for Spanish and the medicine check, and Meta, for Koko's helper. Vercel, Neon, Resend, Sentry, Google and Meta are the whole list. The gateway is a route, not a seventh destination: naming it without naming Google and Meta would be a shorter list than the truth.
What we keep
This is the whole list, table by table. If something is not here, we don't have it.
Your account
- Your email address, so we can send you a sign-in link. There is no password to store, so we don't store one.
- If you sign in with Google — which only appears when we have switched it on — Google hands us your email address, and the name and picture on your Google account. We also keep, in a row of its own next to your account, which Google account it was and the keys Google gives us to prove that sign-in.
- One true/false flag: whether you told us you are old enough to have an account. When you sign up we ask for a birth year, we check it, and then we throw it away. The year is never written down. All that is kept is yes.
- The day your account was made.
- When you ask for a sign-in link, we hold your email address and the one-time code that is in the link. Using the link deletes that row. An unused one stops working after a day, and we haven't written the sweep that clears the dead ones out — so it sits there.
- A sign-in cookie in your browser, and a matching row on our server for each browser you are signed in on: which account it is and the day it runs out. That is how you stay signed in for about three months. Being locked out at the moment you need the card is the worst thing this app could do to you.
The profile you write
- The name you type. A nickname is fine — Koko offers one on purpose, because a real name on a shared card travels further than you might want.
- Whether the profile is about you or about someone you look after.
- An age in whole years, if you choose to fill it in. Never a birthday. A whole number tells a sitter how to talk to a child; a date of birth is an identifier, and we have no use for one.
- The need cards you picked from our library, the ones you wrote yourself, and the order you put them in.
- The notes you wrote in Koko's notebook, and when you wrote them.
There is no box in Koko for a label a doctor gave someone. Not a hidden one, not an optional one — the field does not exist in the database, and a test fails if anyone adds one.
The cards you share
- For each share link: the unguessable part of the web address, the label you gave it, your first name and phone number if you added them, when it expires, and whether you turned it off.
- A frozen copy of the card as it read at the moment you shared it. That is what the reader sees, so later edits never quietly rewrite a card someone is already holding.
- How many times that link has been opened, and when it was last opened. Two numbers on the share, and that is all. No addresses, no browser names, no way to tell one reader from another, and no record of any single visit.
The kid's link
- The link itself, which of the two modes it is in, which language it speaks, and whether you turned it off. You set all of that; your child never does.
- Which of the fixed buttons your child tapped, and the time they tapped it. That is the entire record of a child using Koko. No typing, no name, no account, no device details, no place. There is nowhere in that screen for a child to write anything, so there is nothing for us to read.
- We email you when a signal comes in, so the record also exists in your inbox, and in whatever company runs your email.
Feedback about our wording
If you tell us a sentence in our library reads wrong, what we keep is: which sentence, which language, which version of the library, which category you picked, and the day. No account, no share link, no profile, no free typing — the form has no box to type in, so it cannot collect one.
One catch, and we would rather write it down than let you find it. If the card you are reporting is one you wrote in your own words, then "which sentence" can't be a name out of our library — it is a fingerprint of your sentence instead. That is the same fingerprint our Spanish cache files that sentence under, so someone with both tables can line the two rows up. What that gets them is your sentence and its Spanish. It still carries no name, no account, and no link back to your profile.
We won't dress that up with a bigger word than it deserves. What we can say precisely is: there is no column in that table that points at a person, and no way to join a row of it to your account.
Counting requests, so nobody can flood us
To stop one person hammering the site, we count requests against a bucket. The bucket is a one-way hash plus a secret that changes every day: of an IP address for the wording-feedback form, of the share link for Koko's helper, of the email address and the connecting address for sign-in links, and of your account for the medicine check while you are writing a card. What was hashed is never written to the database, the hash cannot be turned back into it, and yesterday's buckets stop working overnight. A row holds the bucket, the day, and a number — that is the whole table, three of them.
We keep two days of these — today and yesterday. There is no scheduled job behind that: the sweep runs inside the same request that counts one, so the day a counter is written is the day older ones go. If nobody uses Koko at all for a while, the last day's rows sit there until somebody does. That is the whole mechanism, said the awkward way rather than the tidy way, because the tidy way would suggest a clock we have not written.
We'll be straight about this: a hashed address is still data about a person under some privacy laws, even though we can't read it back. That's why it's on this list instead of being called nothing.
When something breaks
When a page or a button fails, we keep one row about the failure so we can find it and fix it. What is in that row: the error's own message, the trace that came with it when we have no shorter fingerprint for that error, which page address it happened on, a rough kind (a page, a button, or something we did not catch), the first and last time we saw it, and how many times. The same error happening again adds one to that count instead of adding a row.
What is never in it is who was there. No account, no email, no sign-in, no IP address, no browser, and nothing you typed into Koko. Before the message and the trace are written down we strip out any email address and any share or kid link that landed in them, and the message is cut off at 500 characters. It is a list of what is broken, not a list of who hit it — and it is here on this page because we started keeping it, which is the rule at the top.
The same error is also sent to a company named Sentry, whose whole business is watching for broken pages. What reaches Sentry is scrubbed by the identical code first — the same email and link stripping, before either copy is written down.
On pages where you are signed in as a caregiver, your own browser also reports its mistakes to Sentry directly — a script that breaks, a button that throws an error while the page is open. That never happens on a card someone opened from a share link, and never on a kid's link screen. Sentry's browser code does not run at all on those two kinds of page, on purpose: a page you share carries nothing extra in it for anyone to trace.
Two more things we chose not to turn on. Sentry can record a video of what is on someone's screen and follow how they move between pages — we turned both off, because this app shows a child's own information and a screen recording would be exactly that. And we did not hook Sentry up the ordinary way, which stamps a fresh random number into every page it touches: two copies of a shared card have to read exactly the same, byte for byte, and a random number stamped into the page would break that. A page you get from us carries no per-page mark for Sentry to trace it by.
The Village, if you send a line to it
The Village is a public page of lines other families wrote for whoever looks after their kid. Nothing of yours is on it unless you opened a card you wrote yourself, read the screen that says what is about to happen, and pressed the button on that screen. Writing a card never does this. It is a separate, deliberate act, one card at a time.
What a Village row holds, in full: the words, which language they are in, whether they are showing, a fingerprint of those same words, and the day. That is the entire table. There is no column for your account, your child, the card the words came from, or any share link — not left blank, absent, and the code that reads that table has no way to ask for one.
Before a single word is written down we take out the names we can find, and then the line is read by a language model whose only two answers are "fine" and "no". A line carrying an email address, a phone number, a link, or a street is turned down rather than tidied up and posted. If that second read can't happen, the line is held back and never shows.
A Village line is the one thing a delete cannot reach. Because nothing in that row points at you, nothing can find it again on your say-so — not you, and not us on your behalf. It is the same fact as "it carries nothing of your family", read from the other side, and the screen you press before sharing says so before you press it. If a line of yours should come down, write to dan@kokosays.com and quote the words themselves. The words are the only handle that table has, which is why they are the only thing we can ask you for.
On your own device, not on ours
Before you make an account, the card you are building is held in your browser's own storage so a refresh doesn't lose your work. It stays on that device until you save it or clear the site data for Koko.
What we never ask for
- A label a doctor gave someone. No field, anywhere.
- A birthday, a home address, or a place.
- A password.
- Your child's own account. Children don't sign in to Koko.
- Who someone is when they open a card you shared. No name, no email, no account, no sign-in, and no record of any single visit. What a reader can hand us on purpose — a question for Koko's helper, or a report that a sentence reads wrong — is described above, and neither carries who they are.
What we don't do
- We don't sell your information, and we don't share it so anyone can advertise to you. Not now, and not quietly later — a change like that would have to be asked for in plain words, and we would rather close the site than make it.
- There are no ads anywhere in Koko.
- There is no analytics tool on any page — not ours, not anyone else's. No counting scripts, no pixels, no tag manager. A shared card loads nothing from any other company at all, and the fonts are part of the site rather than fetched from someone.
- Shared cards and kid links are kept out of search engines, and browsers are told not to pass the link on to anything the reader clicks next.
- We keep no history of questions asked of Koko's helper. There is no chat table in this app.
What leaves our server
Ordinary server logs
Vercel runs the site, and like every website that produces ordinary logs: an IP address, a time, which page was asked for, which browser asked. Vercel keeps those under its own rules, which we didn't set and can't change. We don't download them or keep copies.
Resend sends your sign-in links, and the note that goes to you when your child taps a button. Resend sees the address it is sending to and what the message says.
Language models — say it plainly
Three parts of Koko use a language model, and all three reach it through Vercel's AI Gateway, which passes the text on to whichever company runs the model:
- Koko's helper. When a sitter asks a question, the question, every note in that child's notebook, and any words you typed yourself on the card they are reading are sent to the model, and the model writes the reply. Not a selection of the notes — all of them, every time, because picking which ones looked relevant was our code guessing at the question and getting it wrong. Our own code then decides whether the sitter ever sees it: every set of quotation marks in the reply has to hold your words exactly — whole words, in your order, not a piece cut out of the middle of one, and a hyphen, a colon or a dot counts as the middle of one, so “sugar” cannot be lifted out of “sugar-free” — and name you as the one who wrote them. A reply that quotes something you never wrote is thrown away and replaced with Koko saying it isn't sure and to call you. So is one that mentions medicine, and so is one that leaves a quotation mark open. And any word that tells the sitter to do something — give, put, keep, skip — or not to do it — don't, never, no need to — has to sit inside your own quoted words, not merely somewhere near them; if it doesn't, the whole reply is thrown away too. A quotation that is really yours but forgets to name you is cut out on its own, with the sentence carrying it, and what survives is checked again from the start. Here is the part we can't promise: our code reads words, not meaning, and the instruction words it knows are a fixed list we wrote by hand. A reply that quotes you correctly and then draws its own conclusion around the quote can still get through, and so can an instruction built on a verb we didn't think to list — “run him a bath” is a sentence we would not catch. The same is true in reverse: we look for a handful of ways of saying not to do something — don't, never, no need to — and there are plenty of others. “You needn't call her” and “there's no point calling” both get through, and telling a sitter not to call you is the thing we least want to get through. Nor would we catch a word that is on the list, spelled to miss it: a letter from another alphabet that looks identical, or an invisible character dropped into the middle of the word. That one is worth naming out loud, because it is not a mistake anyone makes by accident. The model has read your notes and whatever the person holding your link typed into the question box, and a question written to talk it into that spelling is how this hole gets used on purpose. In Spanish, Koko doesn't write at all — it hands back your note as you wrote it. Either way, the notes did leave our server to get there, and you should know that.
- Spanish. When you write your own sentence and want it in Spanish, that sentence is sent to a model, and a second model checks the result.
- The medicine check. Koko never carries a dose or an instruction about medicine, so we check the words you write for it — every note you save, and every need card you write yourself, which is the part that actually goes on a shared card. A word list on our own server runs first; then, when a model is available, that text is sent to one for a second look.
Now the part it would be easy to dress up. We have not bought a special route where the model company promises to throw your text away. What we call are the gateway's ordinary free models — Google's Gemini Flash Lite for Spanish and the medicine check, Meta's Llama for the helper and for checking the Spanish. So what happens to that text at the far end is whatever Vercel's terms and each model company's own terms say, not something we have signed for. Getting a no-keeping route is on the list at the foot of this page. Until it is done we would rather write this paragraph than print a promise we haven't bought.
What we can promise is the switch: Koko's helper is off unless we deliberately turn it on, and while it is off, no note is ever sent out to answer a question. Right now it is on. So when someone holding a share link asks Koko a question, that question, every note in that child's notebook, and any words you typed on that card go out to Meta's model, under the ordinary terms described just above. This sentence is read from the switch itself every time the page is drawn, so it says what is true today rather than what was true on 4 August 2026.
One more honest line: our own Spanish cache keeps the translated sentence, filed under a fingerprint of the original rather than under your account. Nothing in that row points at you, which also means deleting your account doesn't reach it — there is nothing in it to find you by.
A share link is a key
This is the part we most want you to read.
A share link works because it is hard to guess. There is no password on it. That means whoever holds the link can read the card, whether you sent it to them or someone forwarded it on.
- It sits in your message history and in theirs, including backups.
- It sits in the browser history of every device that opens it.
- A screenshot or a printed copy keeps working after you turn the link off.
- Someone glancing at an open phone can read the whole card.
Sharing is permanent. Turning a link off stops the page from loading. It does not reach into anyone's memory, camera roll, or paper copy. Set an expiry, share with people you trust, and treat a card the way you would treat telling someone in person.
Deleting things
Here is what actually happens, checked against the database itself.
- Delete your account — the button is on your account page — and everything hanging off it goes with it: your profiles, their need cards, your notes, every share you made and its open count, every kid link and every button-tap under it. That chain is enforced by the database, not by remembering to tidy up. You are signed out and left on the front page. A line you sent to the Village is not hanging off your account — that is what makes it unfindable, and it is why it stays. See the paragraph under this list.
- Delete one profile — the button is at the foot of that child's own page — and the same chain runs for them alone: needs, notes, shares, kid links, taps. Every live share link for that child stops loading at the same moment. Same rule in the database. Both of these ask you to type the name first, because neither one can be undone.
- Turn off a share or a kid link and the page stops loading for anyone who has it, immediately. That one is a button, and it is yours.
- You can delete a single note or a single need card at any time.
What does not go: the Spanish cache described above, any wording feedback, and any line you sent to the Village, because none of the three is linked to you and none can be found by your name. The Village one is the one that is public, so it is the one worth saying twice — deleting your account does not take a line off that page, and there is no column in it that a delete could follow. Rate-limit counters are swept two days wide by the next request that counts one, as described above. Vercel's server logs are Vercel's. Emails we already sent are already in your inbox. And copies a reader kept are theirs.
Both of those are buttons now. On 4 August 2026 you do not have to ask a person to delete anything: one child's Koko goes from the foot of that child's own page, and the whole account goes from your account page. Notes, need cards, shares and kid links you could already remove or switch off yourself. For anything else on this page, write to dan@kokosays.com, which reaches the person who wrote it.
Your say over all of this
Some places — Washington State most strictly of all — treat a list of what helps a child as health information about that child, because it is. We wrote this page as if the strictest of those rules applied everywhere, for everyone, rather than for the people who happen to live in the right state.
So, wherever you are, you can:
- Ask what we hold about you and your child, and get a copy. Write to dan@kokosays.com and a person — not a system — will answer and put it together by hand. There is no export button yet, so give us a few days.
- Fix anything wrong — most of it you can edit yourself.
- Delete it yourself, including your whole account, and have that reach every share you ever made. The single thing it does not reach is a line you chose to send to the Village, for the reason set out above: that row holds no thread back to you, so a delete has nothing to pull on. Write to us with the words and a person can take the line down by hand.
- Change your mind. Sharing is a choice you make one card at a time, and you can turn any link off without turning anything else off.
- Hold us to the no-selling line above. In some states that isn't only our promise — it is a right you could take to court yourself, without waiting for a regulator.
When you type something into Koko and choose to share it, that is the consent. We don't take it as blanket permission for anything else, and there is no other use we put it to.
Children
Koko accounts are for the grown-ups doing the caring. A child is the subject of a profile, never the author of one: the kid's link is made, set up, and switched off by the caregiver who owns the profile, and the child never signs in or types. Our sign-up asks you to confirm you are at least 13. Whether that number should be 18, given that the account holder is agreeing to terms on someone else's behalf, is one of the questions below.
If something goes wrong
If we ever found that someone had got at what families wrote here, we'd say so plainly on the front page as fast as we could, tell the people affected, and tell whoever the law says we have to tell. We won't pretend that can't happen; we'll tell you if it does.
If this project ever stops, we'll say so here first and give people time to save what they wrote. Printed cards outlive websites: treat an old printed card as paper, not as a live link.
What we left blank on purpose
The honest way to have an unfinished legal page is to say which parts are unfinished. These are ours, and inventing values for them would be worse than leaving them open:
- Blank on purpose: the legal name, country, and postal address of whoever operates Koko Says — some laws require them on this page.
- Blank on purpose: whether we have to publish a separate consumer health data policy at its own web address, with the specific contents Washington's law spells out, rather than the single page you are reading.
- Blank on purpose: a route through the gateway where the model company agrees not to keep what we send it, and whether every model company has to be named on this page. Today we use the ordinary free models and their ordinary terms, as it says above.
- Blank on purpose: how long an account nobody has opened in years should be kept before we delete it for you.
- Blank on purpose: the minimum age for holding an account — 13 today, possibly 18.
Until those are filled in, nothing on this page is meant to take away a right you already have where you live.
Changes to this page
We'll edit this page and move the date at the top. If a change matters — if we start keeping something new — we'll say so on the front page rather than quietly editing this one and hoping.