Privacy Policy

Last updated: 9 September 2026

What stays on your device

Dha keeps your practice history, recorded takes, tuning defaults, and app settings on your device. There are no accounts and no sign-in. If you turn on "Record this take," the audio is saved only on your device and is never uploaded.

Using "Delete all local data" removes the app's on-device practice sessions, course and guided-review progress, saved patterns, recordings, preferences, Coach consent, and random installation identifier. Local deletion does not erase Apple purchase history or server records already created for purchase verification, abuse and quota enforcement, notification idempotency, or a consented Coach request. Apple's account controls govern Apple's records; the automatic retention periods below and our support contact govern Dha server records and deletion requests.

Purchases

StoreKit purchases are processed by Apple. Older compatible app versions may send Apple's signed StoreKit transaction and a random installation identifier to our backend on Amazon Web Services to recognise Pro for their Coach requests. We verify the certificate chain and transaction claims, but we do not store the signed JWS.

Apple also sends signed App Store Server Notifications when subscription state changes, including while the app is closed. We verify the signed notification and independently verify its nested transaction, renewal, or app-transaction information when present. We do not store the signed transaction, renewal, app-transaction, or notification JWS.

For each subscription we retain one canonical entitlement record containing: product identifier; active, expired, billing-retry, grace-unavailable, upgraded, or revoked status; expiry; StoreKit transaction and original transaction identifiers; Production or Sandbox environment; the nested transaction's Apple-signed timestamp; the notification or device event's Apple-signed timestamp; our last-updated timestamp; and a deletion timestamp. Separate alias records contain only the random installation or StoreKit app-account alias, a pointer to that canonical subscription, environment, original transaction identifier, event and update timestamps, and deletion timestamp. We use these fields only to recognise current Pro access for older compatible versions, handle restores and Family Sharing, and prevent stale, expired, revoked, upgraded, or unverified records from authorising their Coach requests.

Entitlement and alias records are marked for automatic deletion 90 days after the latest of the subscription expiry, the latest verified entitlement event applied to that record, or our processing/update time. To process notifications once, we retain for at least 200 days after the later of Apple's signed event time or the time our processing begins: a one-way SHA-256 hash of the Production-or-Sandbox environment and Apple's notification UUID; processing or done state; Apple's signed event timestamp; processing/update/completion timestamps; a temporary random lease token and lease expiry while processing; and a deletion timestamp. These idempotency records contain no signed JWS. DynamoDB deletion can occur after a deletion timestamp rather than at the exact second.

On-device coach

Current versions build coaching drills privately on the device from the numeric timing, sam, relative-spacing, and tempo estimates already shown to you. No audio or practice metrics leave the device for coaching. A deterministic offline drill is used when the on-device coach is unavailable.

Older compatible versions may explicitly send a numeric timing estimate, sam estimate when available, relative-spacing estimate, hit/miss counts, tempo drift, taal, and tempo together with a random installation identifier to this backend. The backend returns a prepared drill from those estimates. It does not call an external model or send these requests to a model provider. Those versions ask before the first send.

Abuse prevention and retention

Coach requests from older versions still require an active verified Pro entitlement and pass request-size and input checks. The backend now returns prepared drills without model calls or daily Coach quota writes. Earlier versions of this service created keyed HMAC-SHA-256 daily identifiers from a scope label, the current UTC day, and the installation identifier, original StoreKit transaction identifier, or request IP address. Those rate-limit records contain only the derived identifier, request count, and deletion timestamp, not the raw IP address, and were marked to expire two days after creation. Existing records keep that retention policy.

We do not use entitlement, practice, or rate-limit information for advertising or cross-app tracking.

Contact

Questions or privacy requests: nora@playsoloist.com.

Back to Dha