Privacy Policy for Cadence
Last updated: August 3, 2026
Cadence is a podcast player for Android. cadenceplayer.com is its public
website. This policy describes how the current app, catalog API, and website
handle data. The app stores its library and playback state on your device.
Search, Charts, and Discovery use the Cadence catalog API and Podcast Index. The
optional automatic ad and promotion skipping feature analyzes short windows of
the episode currently being streamed. Speech recognition stays on the phone;
only short timed transcript text and public episode context are sent to
Cadence's classification service as described below. The app sends crash
reports and sanitized diagnostic logs to Sentry for debugging when "Share
diagnostics" is enabled. This is on by default and can be turned off in
Settings. The website uses page analytics and sampled session recordings as
described below.
Who we are
Cadence (com.cadenceplayer.cadence) is independently developed. The current
Android app stores its main app data on your device and does not use a
Cadence-operated account or sync service. Cadence operates a catalog API for
public podcast Search, Charts, and Discovery and an opt-in service for automatic
ad and promotion analysis. Sentry is used for crash reporting and diagnostics
as described below. The public website is hosted separately and does not store
app libraries or playback state.
What we collect
App data. The current version has no sign-in, so catalog requests and diagnostic reports are not tied to a Cadence account. Cadence does not sell personal data or use app activity for advertising or profiling.
The one exception is crash reporting and sanitized diagnostics (see below): if the app crashes, hits an unexpected error, or performs a refresh/backup/DB recovery step that helps diagnose bugs, a technical report or structured log may be sent to Sentry. These reports contain no account or identity data and are not used to track, advertise to, or profile you. You can turn this off with "Share diagnostics" in Settings; local crash handling still remains on-device.
The product website separately uses the limited website analytics described in the Website analytics and session recording section below.
Catalog API
When you use Search, Charts, or Discovery, the app contacts
api.cadenceplayer.com, a Cadence-operated Cloudflare Worker. The Worker asks
Podcast Index for public podcast catalog data and returns a normalized result to
the app.
Search terms are sent in a POST request body to the Cadence API and forwarded to Podcast Index to answer the search. Cadence does not retain search terms in Workers KV or custom application logs. Search responses are not cached by Cadence. Podcast Index may process the search request under its own privacy policy and terms.
Categories, Charts, and Discovery responses may be held temporarily in Workers KV only when Podcast Index response headers permit caching, and never beyond the permitted lifetime. This cache contains public podcast metadata, not accounts, app libraries, playback state, or search histories, and can be discarded without affecting user state.
Cloudflare processes routine request metadata needed to deliver, secure, rate limit, and diagnose the API, such as IP address, user agent, request timing, and route. The catalog routes create no account or stable analytics identifier and perform no behavioral analytics, user-state storage, or AI processing. Automatic skipping uses separate routes, storage, identifiers, and processing described in the next section. For abuse prevention, the Worker derives a keyed pseudonymous rate-limit bucket from the connection IP and sends only that bucket to Cloudflare's rate limiter. The raw IP and derived bucket are not written to Workers KV or custom application logs; the bucket is used only for the active one-minute rate-limit windows.
Optional automatic ad and promotion skipping
Automatic skipping is off until you review its first-use disclosure and choose to enable it. Enabling the redesigned feature requires a fresh versioned consent. On a supported public HTTPS audio episode, Cadence reuses the same partially cached publisher-media bytes used by playback. It examines only the current episode, reads no more than three media-minutes ahead, and does not require or create a complete prepared episode copy.
Android decodes short windows to normalized audio and performs English speech recognition locally with a separately downloaded, checksummed model. Audio and normalized PCM are never uploaded. For each window, the app sends over HTTPS:
- hashed episode and feed identities,
- the public show and episode names,
- the public episode description, publisher or author when available, and total duration,
- a window identifier and SHA-256 hash of that exact normalized PCM,
- the window's absolute start and end times, and
- no more than 180 seconds of bounded, finalized timed transcript cues.
The Cloudflare Worker classifies and independently verifies high-confidence paid ads, other-podcast promotions, and same-show self-promotions synchronously. It returns only verified coverage and segment times, categories, and confidence. Cadence does not write the public episode context or transcript cues to D1, R2, Queues, custom logs, analytics, or other retained application storage. Content-free per-request operational telemetry can retain a request ID, detector version, request duration, cue and character counts, candidate/verifier/accepted counts, outcome, status, and error class. It contains no episode context, transcript text, audio hash, or listening position. Routine Cloudflare request metadata may still be processed to deliver, secure, rate limit, and diagnose the request.
On the phone, Cadence retains the exact PCM-window hash, a hash of the normalized public classification context, verified coverage, detector version, and classified segments for bounded reuse. It does not retain the local transcript. A result is reused only when the exact PCM and classification context reproduce the same local cache identity, preventing a dynamically inserted ad variant at the same URL from inheriting unsafe timestamps.
Cadence uses an app-generated, pseudonymous installation credential and Google Play Integrity results to protect the analysis service from abuse. These are not used for advertising, cross-app tracking, or behavioral profiling. Raw Integrity tokens are not stored in custom logs.
If you separately opt in to anonymous corrections, Cadence can receive the exact media fingerprint, manifest revision, correction type, and corrected segment times. Corrections contain no free-form text or audio. They do not change a shared result automatically and can be published only after independent corroboration and manual review. Turning off automatic skipping stops new analysis and transcript-classification work. Turning off anonymous corrections does not turn off skipping.
Cached results do not reveal which other listeners requested an analysis. Cadence does not sell analysis data or use it to build listening profiles. Cloudflare states that Workers AI customer content is not used to train or improve models without explicit consent.
Automatic skipping does not proxy the publisher's original media stream. Because publishers can dynamically insert different audio into the same episode, Cadence refuses to reuse a result unless the exact normalized window hash is reproduced.
The first public beta does not require payment. If Cadence Pro subscriptions are enabled later, Google Play and RevenueCat will process the purchase. Cadence will receive a pseudonymous RevenueCat customer identifier, product, entitlement status, renewal or expiration dates, and purchase-event metadata needed to grant the subscription. Cadence does not receive or store payment card details. There is no Cadence account, and Google Play provides purchase restoration and subscription management.
Crash reporting and diagnostics
To keep the app stable, Cadence uses Sentry (sentry.io) to capture crashes, unexpected errors, and sanitized diagnostic logs. When "Share diagnostics" is on, Cadence may send technical context such as:
- the error message/category and stack trace,
- the app version/release and platform,
- basic device/OS information supplied by Sentry,
- feed hostnames (not full feed URLs),
- hashed feed-derived podcast identifiers,
- episode/cache counts, and
- recovery steps such as SQLite FTS rebuilds, episode-cache resets, feed refresh outcomes, and backup import/export status.
This diagnostic data is used solely to diagnose and fix bugs. It may include technical app/device information, sanitized error messages, feed hosts, hashed feed/podcast identifiers, counts, and recovery-step names. It does not include:
- raw backup file contents,
- full feed URLs or URL query strings,
- auth tokens, passwords, or API keys,
- file paths,
- playback history or playback positions,
- the full list of subscriptions,
- the shows or episodes you play, or
- app preferences except the fact that diagnostics are enabled or disabled.
Personal-data collection is explicitly disabled (sendDefaultPii is off), and
the app scrubs diagnostic fields before sending them.
Sentry processes these reports on our behalf as a data processor; the data is not sold or shared with third parties for their own purposes. Sentry's own handling of the diagnostic data is governed by its privacy policy.
Website analytics and session recording
When you visit cadenceplayer.com, the website sends usage events to
analytics.garrod.house so we can understand which pages are useful and improve
the site. The standard analytics event can include:
- the page URL, page title, and website hostname,
- the referring page,
- screen dimensions,
- browser language, and
- routine request metadata available to the analytics server, such as the user agent and IP address used to deliver the request.
On a random sample of 15% of visits, the website also records a replay of page
structure, visible text, navigation, scrolling, clicks, and other interactions.
Recordings use the analytics service's moderate masking level, which masks all
form inputs, and stop after a maximum of five minutes. The website does not have
account, search, comment, payment, or other visitor-submitted text fields.
Website analytics and recordings are used only to understand and improve the Cadence website. They are not used for advertising, cross-site tracking, or personal profiling. The website does not send app-library data, subscriptions, playback history, backups, or diagnostic reports to the analytics service.
The website is hosted as a Cadence-operated Cloudflare Worker. Like other web hosting services, Cloudflare may process routine request metadata needed to deliver the site, maintain security, and diagnose service problems.
Data stored on your device
In the current version, core app data is stored locally on your device in a private app database (SQLite via the app's Kotlin/Room persistence layer). It does not leave the phone unless you explicitly export it. This data includes:
- The podcasts you subscribe to (feed URLs and show metadata)
- Episode lists, playback positions, and listened/unlistened state
- Your per-podcast and global preferences (sort order, hide-listened, etc.)
This data stays on the device. It is not backed up to any server we control. It is removed when you uninstall the app or clear the app's storage. The OPML and backup export features write files only when you choose to, and share them only through the destination you pick in the system share sheet. Backup file contents are never sent in diagnostic logs. Cached publisher-media ranges, model files, analysis-window hashes, and skip segments are derived data and are excluded from Cadence backups. Android bounds the shared media cache to 256 MB and ages analysis-window state with that cache.
Network activity
Cadence needs an internet connection to find and play podcasts. The app uses:
- Cadence catalog API and Podcast Index: Search, Charts, and Discovery
contact
api.cadenceplayer.com, which retrieves public catalog data from Podcast Index. Search terms are forwarded as described above. - Public podcast RSS feeds: direct requests fetch each show's episode list and metadata. Adding a feed by URL uses this direct path and does not send the supplied URL through catalog Search.
- Episode media hosts: direct requests stream or download the audio or video served by the podcast publisher.
- Cadence ad-skip analysis service and Cloudflare Workers AI: only after automatic skipping is enabled, hashed identities, public show and episode context, an exact PCM-window hash, coverage, and bounded timed transcript cues are processed as described above. No audio is uploaded.
- GitHub release assets: downloads the versioned, checksummed local speech model on an unmetered connection by default, or on cellular only after the user enables the explicit override.
- Google Play Integrity: protects the optional analysis service from automated abuse.
- Google Play and RevenueCat: process subscription and entitlement state only if paid Cadence Pro access is enabled and used.
- Sentry: crash reports and sanitized diagnostic logs are sent only when "Share diagnostics" is enabled.
The Cadence catalog API does not proxy RSS feeds or episode media. Catalog requests do not include a Cadence account, advertising identifier, or custom tracking token. Cloudflare, Google Play, RevenueCat, Podcast Index, Sentry, and podcast publishers process their respective requests under their own privacy policies.
Permissions and why they are needed
The current Android release manifest contains the permissions below. Some are
declared directly by Cadence and some are merged from AndroidX or media
dependencies at build time. Cadence does not use these permissions for
advertising, behavioral profiling, or undisclosed data collection. The
INTERNET permission carries the catalog search terms and optional diagnostics
described in this policy, along with public podcast and media requests.
| Permission | Why it is present |
|---|---|
INTERNET |
Contact the catalog and optional transcript-classification APIs, fetch RSS feeds, stream episode media, and download the local speech model. |
FOREGROUND_SERVICE / FOREGROUND_SERVICE_MEDIA_PLAYBACK |
Keep playback running and show the media notification while the app is in the background. |
POST_NOTIFICATIONS |
Show playback/download notifications on Android 13+; the app asks before using notification surfaces. |
WAKE_LOCK |
Allow playback and scheduled background work to continue while the screen is off. |
ACCESS_NETWORK_STATE |
Let networking and background-work libraries check whether the device is online before attempting work. |
RECEIVE_BOOT_COMPLETED |
Let AndroidX WorkManager restore scheduled background work after a device reboot; Cadence does not start playback on boot. |
com.cadenceplayer.cadence.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION |
App-scoped AndroidX permission that protects non-exported dynamic broadcast receivers inside the app. |
Cadence does not request location, contacts, microphone, camera, calendar, storage/media-library access, advertising identifiers, or any other sensitive permission. The release permission set is generated at build time from the app and its libraries. Google Play Data safety declarations are based on the app's actual collection and sharing behavior, including optional Sentry diagnostics, not on permissions alone.
Children's privacy
The Cadence app does not knowingly collect personal information from anyone, including children. The current version contains no advertising or in-app behavioral tracking. Neither the catalog nor automatic-skipping service creates behavioral profiles. Automatic skipping and anonymous corrections are opt-in. The website analytics are not intended to identify visitors. Crash reports and sanitized diagnostics can be disabled in Settings.
Changes to this policy
If this policy changes, the updated version will be published at the same location with a revised "Last updated" date.
Contact
Questions about this policy can be raised via email at austin.r.garrod+cadence@gmail.com.