Read this first
wandkit is operated by Flabbergast, a product studio in Zagreb, Croatia. Flabbergast is the controller for this website and for dashboard accounts, and the processor for the end-user data your app sends, on the terms in the data processing addendum. This page describes what the SDK and the dashboard actually do with data today, written against the code, and it is kept in step with the code as the beta moves.
An earlier version of this page said wandkit generates AI suggestions inside your own workspace. That was never true. There is no AI or machine learning processing in wandkit anywhere. No model, ours or a third party's, receives your data, your users' events or their feedback.
Questions, corrections, or a request about data we hold: info@wandkit.app. It is the only address that reaches us.
What wandkit processes
Everything the SDK sends is scoped to one project. An API key belongs to a single project, and the board and erasure queries are filtered by that project's id, so an action in one project cannot reach another's rows. Account and organization data sits above projects. In the intended arrangement you are the controller of your end users' data and wandkit is the processor acting on your instructions. That relationship is set out in the data processing addendum, which is part of the beta terms.
Dashboard account
Who signed in
Your email address, your name and a profile picture URL, taken from the Google account you sign in with. Google Sign-In is the only method the dashboard offers. Alongside it: your organization, your role in it, and the invitations you sent or accepted.
SDK
Product usage events
The event name your app calls, the properties your app attaches, when it happened, the SDK platform and version, the install id, and your own user id once you call identify(). wandkit never invents an event. It stores what you send, so the properties are your decision to make.
SDK
Survey responses
Star ratings, thumbs, selected options and free text, tied to the user who answered and the form that asked. Free text is whatever your user typed, so treat that column as capable of holding anything at all.
SDK and dashboard
Feedback board content
Posts, threaded comments, votes, follows, reports and display names, plus image and video attachments (10 MB per image, 50 MB per video, up to five per post). Each post also carries device context recorded at submit with no separate prompt: platform, OS version, your app's version, device model and locale. Every post created through the SDK is held pending until a team member approves it.
SDK
Push device tokens
The APNs token, the install id, the device id, the platform, and your user id once identify() has run. logout() detaches that id from the device, so a shared phone stops receiving the previous account's notifications.
Dashboard
Subscription state
If you connect RevenueCat, opening a user profile sends that user's id to RevenueCat and displays what comes back. Nothing about the subscription is written to our database, so there is no stale copy to leak or to erase.
SDK and web
Referral install matching
A referral link opens a hosted web page, which records device signals from the browser. On first launch your app can send a comparable set, and the backend scores the two against each other to work out which visit became which install. When a campaign pays out, wandkit also stores the reward grant, the state it is in, each retry, and what the entitlement provider returned. Full field list below.
Dashboard
Derived sessions
A user profile shows sessions, but no session is stored anywhere. They are computed at read time by grouping that user's event timestamps into runs with no gap longer than 30 minutes, over a 90 day window. Close the page and they cease to exist.
The referral fingerprint, in full
This is the part of wandkit that most resembles tracking, so here it is without abbreviation. It runs in two places: on the hosted referral landing page in the browser, and once per install if your app calls the detection method after configure. Its only job is to credit an install to the person who invited it. It is not marketing attribution and it does not follow anyone across other apps or sites.
- User agent string
- Preferred language and the full language list
- Time zone name and UTC offset in minutes
- Platform
- Screen width and height, viewport width and height, device pixel ratio
- The client's own clock reading when the request was made
- The IP address the request arrived from
- From the app side only: the install id and the app's first-launch timestamp, so the attempt can be tied to the install it is claiming for
The landing page record is attached to the referral link that was opened. The install-side record is attached to the install id, and keeps the score and, where one was found, the referral it matched.
Landing page records are deleted seven days after they arrive. Install match attempts are deleted after fourteen. The match is a score, not a certainty, and a wrong match costs an inviter a credit rather than exposing anything.
What the SDK does not do
- It does not read the advertising identifier or the vendor identifier. The install id is a random UUID the SDK generates and keeps in the app's own preferences, and it disappears when the app is deleted.
- Screenshot bug reports are off unless you switch them on. When on, iOS tells the SDK that a screenshot was taken but hands over no image. The SDK re-renders your app's own window itself. It never opens Photos, and there is no permission prompt because there is nothing to ask for. The image is uploaded only if the user submits the report.
- Anonymous users are read only. Posting, voting and commenting all require identify(), which means an identifier you chose and control.
- The in-app board runs in a web view. It keeps two flags in the device's local storage: a last-seen marker for the board, and whether the display name prompt has already been shown.
- Behavioral event analytics is coming but is not built yet, so nothing here charts, funnels, cohorts or groups events across users. The one aggregate is a per-user, per-event-name occurrence counter, which is what makes "show this survey the third time" work.
Retention and the cleanup worker
A worker runs on a fixed interval and deletes by age. These are the horizons in the code, not intentions:
- Referral landing page records: 7 days
- Referral install match attempts: 14 days
- Push devices that have not re-registered: 90 days. A live install refreshes its registration on every launch, so anything staler than that is an uninstalled app.
- Attachment upload slots never bound to a post: 24 hours. The file goes first, the row second, because a row without a file is a broken attachment while a file without a row is only wasted space.
- Expired sign-in tokens: cleared on every pass
- Invitations in a terminal state: 90 days by default
Events, survey responses and board content have no automatic expiry today, and there is no setting that would give them one. Deleting the project is the only thing that removes them in bulk: that cascades across every table, but it does not currently sweep attachment files out of object storage. Both gaps are named again below rather than quietly left out.
Erasure
The dashboard has a right to erasure action. An organization admin runs it against one project and one of your user ids. It is a single transaction, so it either completes or changes nothing, and it reports back what it touched.
- Posts and comments by that user: authorship removed, text left in place. This is deliberate. Deleting the text would blank threads other people contributed to. The thread still shows that an end user wrote it, without saying who.
- Votes, comment votes and follows: the identifier is rewritten to a fresh placeholder minted for that erasure. Counts stay correct without a recount, per-user dedup keeps working, and nothing links the rows back to a person.
- Reports that user filed: deleted. A report is their own statement, not someone else's contribution.
- Any ban recorded against them: deleted.
- Push devices: deleted, so notifications stop.
- The user record itself, display name included: deleted, in both its identified and device-keyed shapes.
You get back a count for each category, which is what you would attach to a compliance record.
What erasure does not reach, stated plainly, because a compliance record built on the assumption that it does would be wrong. The raw event log and its per-event counters are untouched. So are survey responses and their answers, and so are referral match attempts and reward grant records. Those rows are keyed by an internal user key that contains the id you passed to identify(), so the identifier survives in them. Attachment files the user uploaded also stay in object storage, since the posts holding them survive as anonymized rows. Closing this is the first item in the missing list below. Until it is closed, a full erasure means running the action and then deleting the project, or removing those rows yourself.
There is no equivalent one-user export yet. Today you can export a form's responses as NDJSON from the CLI and filter them yourself.
Where data goes outside wandkit
- Google, for dashboard sign-in.
- Apple, for push delivery through APNs.
- App Store Connect and Google Play, if you connect a store, for builds, review state and store reviews.
- RevenueCat, if you connect it. The lookup sends the user id you gave us.
- Resend, which delivers our outbound email. Mail is sent from noreply@wandkit.app.
- The S3-compatible object storage bucket that holds attachments.
- Slack or Discord, only if you turn that integration on. From then on the event content reaches the webhook you configured, including the feedback title, an excerpt of the body, the author's display name, the platform and the app version.
- An OpenTelemetry collector, which receives the backend's own traces, logs and metrics.
Which hosting provider and which storage bucket those run on is deployment configuration rather than something the code names, so this page cannot yet list them with the precision a sub-processor list needs. Producing that list is part of the work below.
What has to be added before this becomes a policy
Naming the gaps is more useful than implying they are handled.
- Required A named legal entity, acting as controller for account data and processor for end user data, with its address and registration details.
- Required A data protection officer or a named privacy contact, and a stated response time for requests.
- Required A countersigned copy of the data processing addendum, on request. The addendum itself is part of the beta terms today.
- Required Erasure that also reaches the event log, survey responses and reward grant records. Today it covers board content, reports, bans, push devices and the user record only.
- Missing A sub-processor list naming each vendor and where it runs.
- Missing A retention policy for events, responses and board content, which currently expire on nothing.
- Missing Removal of attachment files from object storage when a project is deleted.
- Missing A per-user export, so an access request does not have to be answered by hand.
- Not offered There is no choice of data region. Everything runs in one place and wandkit has no residency concept built into it.
- Not offered No SOC 2 report, no SSO, SCIM or MFA, no admin audit log, no uptime commitment.
Getting in touch
info@wandkit.app reaches us, and it is the only address that does. sales@, support@, hello@ and security@ do not exist. If you are an end user of an app built with wandkit, the fastest route is that app's developer: they hold the account you are asking about and they can run the erasure themselves. We will help them do it.