UniClipboard

Privacy & data collection

What UniClipboard collects, why it is collected, what is never included, and how to turn it off.

Edit on GitHub

UniClipboard's main privacy boundary does not change: clipboard content only syncs between your paired devices, and it is end-to-end encrypted for the whole trip. Diagnostics and usage analytics are separate helper channels used to find crashes, debug sync failures, and understand which platforms and flows need attention first.

Both channels are controlled under Settings → General → Privacy. They are on by default. The first-start notice lets you disable both at once; later you can control them separately. Changes take effect without restarting the daemon.

Two Separate Toggles

ToggleScopeDefaultDestination
Send diagnosticsCrashes, errors, warning logs, performance traces, frontend diagnostics, and sampled Replay. Used to answer "why did it break?"OnSentry, with separate frontend and backend projects when a DSN is configured in the build
Send usage analyticsAnonymous product events such as first open, pairing funnel, first sync, and sync success / failure / deferred outcomes. Used to answer "where are flows getting stuck?"OnPostHog Cloud US ingestion endpoint when a release build has a project key configured

Turning either toggle off drops the next matching event; no daemon restart is required. When usage analytics is off, product events do not reach the remote sink and release builds do not write a local analytics log.

Why We Collect It

  • Find crashes and exceptions. Diagnostics tell us which version, platform, or process role is failing.
  • Find setup and pairing drop-offs. Usage analytics shows whether people get stuck at first launch, device naming, invite redemption, passphrase confirmation, or handshake. A setup-completion anchor lets us separate "started setup but didn't finish" from "finished setup but didn't pair".
  • Measure unlock reliability. When you launch the app on a device that has already been set up, we record whether the space unlocked, or which category of failure happened (wrong passphrase, corrupted key material, missing space, or internal error). The passphrase itself is never sent.
  • Measure sync reliability. Sync events separate success, failure, known-offline deferral, and the stage where a failure happened.
  • Prioritize work. Aggregated dimensions such as platform, version, locale, timezone, and paired-device count help us focus on the paths with the largest impact.

This data is not used for ad targeting, is not sold to third parties, and is not used to recover, read, or analyze your clipboard content.

Local keyboard-state access

If you enable the Quick Panel's modifier double-tap trigger, the GUI process samples the local keyboard state while that trigger is active. It reduces each sample immediately to two booleans: whether the selected modifier is down and whether any other key is down. Raw keys are not logged, persisted, indexed, included in diagnostics, or sent to another device or service. Disabling the trigger stops the sampling worker. On macOS this capability requires the separate Accessibility grant; native Wayland sessions are reported as unsupported.

What Diagnostics Include

Diagnostics include the minimum context needed to understand failures:

CategoryIncluded
App and platformApp version, release channel, OS platform, frontend webview platform, and process role (GUI host / daemon / CLI / webview).
Diagnostic device identifierA persistent random device ID used to correlate crashes, logs, and frontend errors from the same device.
Errors and logsPanics, exceptions, error events, warn / error logs, and frontend logs at info or above. Sensitive fields are replaced with [REDACTED] before sending.
Performance and breadcrumbsSampled performance traces plus navigation / action breadcrumbs used to reconstruct the path around an error.
Frontend ReplaySampled Sentry Replay for frontend UI errors. It is not sent when "Send diagnostics" is off.
User-submitted feedbackOnly when you submit the feedback form: the message you wrote and the optional email address you entered.

What Usage Analytics Include

Usage analytics uses separate anonymous IDs. They are not derived from the pairing DeviceId, and they do not participate in sync or trust decisions.

Every product event carries these shared fields:

FieldMeaning
anonymous_user_idRandom UUIDv7 used for anonymous retention metrics on devices that have not joined a space.
analytics_device_idRandom UUIDv7 used for device-level slices; independent from the business device ID.
space_person_idRandom UUIDv7 shared by every paired device in the same space, so they aggregate into one anonymous person in retention metrics. Empty before you join or create a space.
session_idRandom UUIDv7 for one process run.
app_version / app_channelApp version and release channel.
os / os_version / archOperating system, OS version, and CPU architecture.
locale / timezoneSystem locale and timezone.
install_sourceInstall-source enum; currently unknown when not detected.
is_first_runWhether this process run is the first run.
active_device_countNumber of paired devices read once at process startup.
space_id_hashFirst 16 hex chars of an irreversible SHA-256 hash of the space ID; empty before joining a space.

The current allowed product event scope is:

Event familyEventsPossible event fields
Lifecycleapp_openedNo event-specific fields; uses only the shared context fields above. Emitted once per process start so that DAU / retention can be computed.
First activationapp_first_open, setup_started, device_name_setSetup entry and device-name length bucket. The raw device name is not uploaded.
Pairingpairing_started, pairing_succeeded, pairing_failedPairing method, peer OS, duration, and pairing failure reason enum.
First syncfirst_clipboard_sync_attempted, first_clipboard_sync_succeeded, first_file_sync_succeededSync direction, peer OS, transport type, duration, and payload-size bucket.
Sync reliabilitysync_attempted, sync_succeeded, sync_failed, sync_deferredDirection, payload type, payload-size bucket, transport type, peer OS, sync latency, failure reason / stage, and deferral reason.
Mobile syncmobile_device_registered, mobile_clipboard_synced, mobile_auth_failedSync direction, payload-size bucket, and mobile auth failure kind enum. The raw Authorization header, username, and password are never uploaded.
Update lifecycleupdate_check_performed, update_notification_shown, update_dialog_opened, update_dismissed, update_action_invokedCheck source (startup / scheduled / manual / window-show top-up), outcome (available / up-to-date / failed), failure-kind enum, notification delivery-status enum, dialog open source, dismiss source, action kind and outcome, install kind (app / deb / rpm / appimage / unknown), and the new version string. Release-notes text, download URLs, byte counts, hostnames, and usernames are not uploaded.

Any new product event or field must continue to follow this privacy boundary and must be reflected in the public docs.

What Is Never Included

UniClipboard does not put these values in diagnostics or usage analytics:

  • Raw clipboard content: text, RTF, HTML, image pixels, or file bytes.
  • Raw file names, raw file paths, or home-directory paths.
  • Space passphrases, MasterKeys, KEKs, private keys, tokens, or credentials.
  • Search queries.
  • Usernames, hostnames, or email addresses; the only exception is an email you explicitly enter in the feedback form.
  • Raw space_id values or the business DeviceId used for pairing.
  • Exact payload sizes; product analytics uses size buckets. Successful sync latency in milliseconds may be uploaded for reliability percentile analysis.

Any HTTPS service provider can see the source IP at the network layer. UniClipboard does not write IP addresses into diagnostic or usage analytics event fields, and it does not use them for product analysis.

How To Turn It Off

Go to Settings → General → Privacy:

  • Turn off Send diagnostics to stop frontend / backend Sentry errors, logs, traces, Replay, and breadcrumbs.
  • Turn off Send usage analytics to stop product events.

The first-start notice's Disable action turns both off at once. Disabling these channels does not affect clipboard sync, LAN-only mode, local history encryption, or local search. It also does not delete the local anonymous IDs that have already been generated; keeping them avoids counting the same install as brand new if you accidentally turn a toggle off and later re-enable it.

On this page