WhyBee answers questions from children aged 3–14. The product rests on three principles: safety before the answer, the parent is the customer while the child is the user and data minimisation. This page describes — honestly and verifiably — what data leaves the app and where it goes.
The Russian edition is the canonical one: its wording is what our code pins and our tests verify. This translation follows it and is provided for convenience.
AI disclosure.
Answers are produced by artificial intelligence (Anthropic's Claude model), not by a human, and AI can be wrong. Inside the child-facing interface the child is told this in age-appropriate language; safe AI use is covered by separate learning material for children.
This is the exhaustive allow-list. It is not a promise in prose: the list is pinned by code and verified by tests (see «How this is enforced» below).
The allow-list is held by architecture, not by agreement. Anyone can check the sources:
backend/internal/llm/imports_test.go
backend/internal/transparency/binding_test.go
backend/Makefile
backend/Makefile
.github/workflows/ci.yml
Beyond that: the narrow LLM request signature (§5) carries no child object, and a binding test enforces it — any new field in a model request must either be declared in the «sent» allow-list or marked as transport, or CI turns red. This page itself is covered by tests too: they fail CI if its allow-list diverges from the architecture test or the CI guards. The page has to stay honest by construction.
Third parties that process child-related data.
| Subprocessor | Role | Receives | Does not receive | Retention |
|---|---|---|---|---|
| Anthropic PBC | Answer generation (the Claude LLM) and post-moderation. | the question text, the age band, conversation turns, interest topics, descriptions of parental stop-topics; for independent post-moderation — the generated answer and its parts, the answer mode and the flag for previously blocked questions in the conversation; for the weekly letter — the locale, the topics and the question counter. | the name, the birth year, the e-mail, identifiers, voice. | inputs and outputs of the interactive API (question-answer and moderation) — within 30 days (Anthropic's formal policy; the actual default was lowered to 7 days on 2025-09-14, final confirmation pending the signed DPA); Message Batches results for the weekly digest (de-identified aggregates only — topics and a counter, no question text) — deleted as soon as we collect the results (upper bound — up to 29 days). Nothing is used for training (commercial terms); a DPA is in place. An exception on top of these windows: content flagged by Anthropic's automated trust & safety systems (a blocked unsafe question, for example) may be retained for up to 2 years, and classification scores for up to 7 years; this applies on top of ZDR/DPA and is outside our control. ZDR is not required: PII does not reach prompts by design — the code picks fields by the §10.1 allow-list. One clarification to «by design»: the interest topic is the only field formulated by the model rather than by code. The model is forbidden from naming a private individual (KQA-057), and when extraction is unavailable the topic is «misc» rather than a word from the question; but that prohibition lives in the prompt, not in a code check, so for the topic «by design» means a rule for the model. For the weekly letter that is the entire text that leaves: there is no question text in it. Anthropic's Covered Models (Fable 5 / Mythos 5, for example) require a mandatory 30-day retention without ZDR — we do not run on them. |
| Amazon Web Services (Amazon SES) | Delivery of parent notifications and of authentication mail (KQA-213): the address-confirmation code and the access-recovery code physically travel through this same vendor. | the parent's e-mail, the event category, counters, interest topics and the text of the weekly letter (a narrative assembled from topics and counters). Separately — authentication mail: the parent's e-mail and a one-time code that confirms the address at sign-up or restores access (KQA-213). Those letters are sent by the Supabase auth flow, but through this same delivery vendor. | the question text and the answer text, the child's identifier and their age band — the product's mail does not carry them, the parent sees those only in the app, behind auth. The exception is support correspondence: our replies go out through this same vendor, so it sees what the parent wrote in that correspondence. | letters leave from the eu-north-1 region (Stockholm) — delivery is processed in the EU. An address whose delivery bounced, or which produced a spam complaint, lands on the SES suppression list and stays there until explicitly removed: that list has no expiry — which is why deleting an account separately asks SES to remove the address (KQA-156). Delivery event publishing is not enabled, so SES hands delivery logs neither to us nor to third parties. A separate DPA signature is not required and does not exist: AWS Service Terms §1.14.1 incorporate the Data Processing Addendum into the service terms themselves. the channel is encrypted by force: our configuration set has a TLS Required policy, meaning a letter is not sent at all if the recipient's server does not offer a secure connection (the SES default is opportunistic TLS, under which the letter would have gone in plain text). Account deletion reaches that list: together with the data in our database we ask SES to remove the address from the suppression list, and the request is not made only once — on failure it is retried with growing intervals over weeks (KQA-156). An honest caveat: the list is not ours, so the confirmation is SES answering «the address is gone», not a record of ours; for the same reason we do not promise guaranteed success — if SES never confirms the removal, the retries end, the failure lands in our error log and is handled by hand per the deployment runbook. A topic is a short label formulated by the model; the model is forbidden from naming a private individual — instead of «Alexandra» it must return what the question is about («tears»), and if there is nothing else in the question — «misc» (KQA-057). Unavailable extraction no longer takes a word from the question: the fallback returns «misc», that is, it loses the interest-map record rather than publishing the child's word (§4.3). An honest caveat: the prohibition lives in the prompt, not in a validator — only a model reading the question can tell a sister's name from «Mars», so the residual risk of a model error remains. Names of public and fictional figures, places and planets are not covered by the prohibition: those are genuine interests, and the map exists for them. |
| Porkbun | Mail intake for the domain's addresses: a letter is forwarded to our mailbox. | a letter arriving at the domain's addresses: the return address, the subject, the text and any attachments. A parent's reply to the weekly letter lands here too. | access to our database: question and answer text, interest topics, the birth year and the child's identifiers do not travel there — the vendor sees what the letter itself says. The product's outgoing mail — notifications and weekly letters — goes through the delivery vendor, bypassing the forwarding. | the provider does not publish a retention period for forwarded mail — so we do not promise one. the support address is ordinary e-mail: a letter travels by the general rules of e-mail, not through the app's protected channel. |
| Google (Gmail) | The mailbox that receives the forwarded support mail. | the same letter in full — the return address, the subject, the text and any attachments. | access to our database: the child's data reaches it only to the extent the parent named it in the letter themselves. The product's mail — notifications and weekly letters — does not pass through this mailbox. | correspondence sits in the mailbox until we delete it; after deletion the provider states about 2 months for full erasure from active systems and up to 6 months in encrypted backups. our replies are sent from this same mailbox; the reply itself leaves through the same delivery vendor as the product's mail. |
| Supabase | Parent authentication (sign-in, password recovery). | the parent's e-mail and credentials (the password is stored hashed on Supabase's side), the auth user identifier, and the one-time address-confirmation and access-recovery code — issued and stored by Supabase, delivered by our mail vendor (KQA-213). | children's data — name, birth year, question and answer text, interest topics: those live in our own database (the managed Postgres below), not in Supabase. Our backend reads only the parent identifier out of the token. | the auth record lives as long as the account does: deleting the account (KQA-014) removes our data in a single transaction and then deletes the auth user through a separate admin call. an honest caveat: that admin call needs a service key configured per environment. Without it our own data is still deleted in full, but the Supabase record remains — that is open debt KQA-169, not a promise, and until it is closed we do not claim the e-mail disappears from this subprocessor on every deletion. Production and test environments are separate projects, so test accounts never mix with real ones. The letters of that auth flow — the address-confirmation code and the access-recovery code — are not sent by Supabase itself: since 2026-08-02 it is configured to use our delivery vendor, Amazon Web Services (Amazon SES), so the access code physically passes through it. |
| Railway | Backend hosting and managed PostgreSQL. | everything the product stores: child profiles (name, birth year), question and answer text until anonymization, interest topics, activity events, subscription state. This is the infrastructure the database itself runs on — not a separate recipient we hand an extract to. | no separate export is made: access is limited to our service and the team's administrative access. | the product's own windows: text is anonymized on the retention window, the rest is deleted with the profile or the account. Platform backups follow the platform's own schedule. listed as a subprocessor precisely because children's data physically sits there, not because we send anything to it. Environments (integration / staging / production) are separated; production data never reaches the test ones. |
| RevenueCat | Subscription bookkeeping: purchase validation and webhooks about its state. | the parent identifier (the same UUID we use) and subscription events — purchase, renewal, cancellation, expiration, transfer. | the child's name and birth year, question and answer text, interest topics, the parent's e-mail. The subscription is attached to the parent as the payer; the service knows nothing about the children. | subscription events are kept by the service under its own terms; on our side we keep the derived access state and an event log, deleted together with the parent's account. the payment itself bypasses us: the card and payment details are taken by Apple (next entry), and all we receive is the fact that a subscription is active or not. |
| Apple | Taking the subscription payment and delivering notifications to the device. | the parent's payment details — directly, through the App Store: they never pass through our server and we never see them. Additionally the device push token and the notification text (see the «Apple (Apple Push Notification service)» entry). | the child's name and birth year, question and answer text, interest topics. | per App Store terms. listed separately from the push provider because these are two distinct roles of one vendor: payment is a mandatory part of an in-app subscription on iOS, push is notification delivery. We can neither pick a different payment intermediary nor see the card data. |
| Hugging Face | Public storage for voice model files. | the device's IP address and the path of the requested file — at the moment the app downloads the neural narration model once. The request goes straight from the device; our server takes no part in it. | question and answer text, the child's name and birth year, interest topics, the parent's e-mail — narration runs on the device and sends nothing out. | per the service's own terms: this is an ordinary public file download, we hold no account there. listed not because it receives family data but because it sees a request from a specific device — and the subprocessor list promises to be exhaustive. The asymmetry that kept this entry missing until now: the policy named this vendor from the start, while the guard only checked one direction (canon → policy) and stayed silent about the reverse (KQA-178). |
| Apple (Apple Push Notification service) | Delivery of push notifications. | the device push token and the text of the notification itself: for an escalation — a static warning template (without the child's name and without the question text), for a digest — a generic «a new overview is ready» without topics or counters. | the question text and the answer text, interest topics, counters, the child's identifier and age band — the parent sees the detailed digest only in the app, behind auth. | a notification is stored by Apple only until it reaches the device: if the device is off or offline, APNs keeps the LATEST message for a limited time and discards it afterwards. The push token lives in our `parent_devices`, is deleted together with the family (KQA-005) and is removed on sign-out (KQA-052) — the latter on a best-effort basis: if the removal request did not go through (the device was offline, say), the token stays until the next successful attempt, or until another parent signs in on that device and the token is re-pointed to them. No separate processing agreement is signed — the APNs terms are part of the Apple Developer Program License Agreement. the push token, the fact of activity and the text of the generic notification are child-related data, which is why the provider is listed as a subprocessor. Android (FCM) stays schema-ready and is not named in the list: there is no sender, and until one appears Google receives no push data. |
The product is designed for children's data protection requirements (COPPA in the US, GDPR-K in the EU). Data minimisation: about a child we store only a name and a birth year; personal data does not reach LLM prompts by design.
Only the parent is authenticated. The consent point is registering the first child: without active parental consent the child features are unavailable.
An honest caveat: today's checkbox attestation of consent is not by itself verifiable parental consent under the COPPA standard (the FTC requires stronger methods). This is a deliberate MVP placeholder; the target method is a legal decision (R4). We do not claim more than what is actually enforced.
The age band is set by the parent; there is no separate verification of the child's age — that follows from data minimisation, it is not a gap. IP addresses are deliberately not recorded (an IP is itself personal data).
The editions reviewed when assessing whether the child scenario is permitted (R3). The dates are the versions we read.
GET /v1/export, at most once an hour.No advertising surveillance: there are no hidden behavioural profiles beyond the interest map that the parent sees explicitly.
We give children level-appropriate learning material about safe AI use — right inside the child-facing interface: what an AI helper is, that it can be wrong, that personal secrets should not be shared. A parent guide on talking to your child about AI is in the works and is not in the app yet.