Skip to content
OddlyticsRelease 1.0.2

Privacy & Data ​

Oddlytics runs entirely on infrastructure you control. Odd Omens doesn't run a server for it and never receives your events.

What the App Sends ​

The Swift package sends only the events you track. Each event carries the name and metadata you pass, plus a few fields it adds itself: the appId, a per-launch session ID, a user ID, a device ID, the platform and the time. On iOS, the user ID and device ID are both the device's identifier for vendor. The full list is in What Is Collected Automatically.

Events go to one place: the Worker address you pass as endpoint, over HTTPS if that address uses it. The package doesn't contact anything else.

It doesn't collect the device model, OS version, locale, location, advertising identifier, contacts or any other personal data, and it asks for no permissions. Whatever you put in metadata is sent as is, so leave out names, emails and other personal details.

What the Server Stores ​

The Worker stores each event as one row in your D1 database:

ColumnContent
event_nameThe event name.
app_idThe app's appId.
timestampWhen it was tracked.
platformiOS from the Swift package, or what another client sends.
metadataYour metadata as JSON.
session_idThe launch's session ID.
user_idThe user ID.

It doesn't store the device_id field or the sender's IP address. Two more tables hold dashboard settings only: event_aliases (event display names) and app_settings (app display names and icon URLs).

Cloudflare carries the requests and hosts the database, so its own logging and data handling apply to your Worker. See Cloudflare's privacy policy for those.

Who Can Read Your Data ​

  • Recording events needs the API key.
  • Reading stats does not. The GET endpoints under /stats (overview, events, timeline, groups, users and user activity) and GET /aliases answer anyone who knows the Worker's address. A user's activity includes their user ID and each event's metadata.
  • The dashboard contains the API key in its JavaScript, because it is built into the static files.

Treat the Worker address and the dashboard as private: protect the dashboard with Cloudflare Access (see Installation), and don't publish the Worker URL or the key in public code. An API key built into an app can be extracted from the app, so expect that anyone determined can send events to your Worker.

What the Dashboard Sends ​

The dashboard talks to your Worker. Once a day it also asks GitHub's API (api.github.com) for the latest Oddlytics release, to show an update notice. App icons load from whatever URLs you set in Customize App.

Its preferences (Pretty Format Event Names, Default Time Range, Compact Mode) and the update check's state are kept in your browser's local storage.

Deleting Data ​

From the dashboard:

  • One event: open a user, then click the trash icon next to the event in Recent Activity.
  • Everything for one person: open the user and click Delete User Data. This removes their events from every app.
  • Everything for one app: open the app and click Delete App Data.

The same actions are available through the API. To remove all events at once, run SQL against D1 from packages/worker:

bash
npx wrangler d1 execute oddlytics-db --remote --command="DELETE FROM events;"

Deleted rows can still be restored from D1's Time Travel history until it expires (7 days on the free plan, 30 days on Workers Paid).

Exporting Data ​

Export the whole database as SQL:

bash
npx wrangler d1 export oddlytics-db --remote --output=oddlytics-backup.sql

If You Ship Oddlytics in an App ​

The identifier for vendor counts as a device identifier, and it lets you link one person's activity across all of your apps that report to the same server. Describe this in your app's privacy policy and in its App Store privacy details.

Odd Omens is a one-person studio building privacy-first software.