StayTuned Feed Reader Privacy Policy
Effective date: 2026-09-10
StayTuned Feed Reader is a local-first browser extension. The developer does not collect, receive, sell, share, or monetize personal data or usage data. There is no StayTuned account, project-hosted backend, analytics service, advertising network, or tracker.
The extension does contact hosts outside your device, and each of them is a host you named:
- The feed sites you subscribe to.
- A site whose address you paste while asking the extension to find its feed.
-
api.notion.com, and only when you choose the optional Notion sync backend and connect it. - A webhook endpoint you configured, and only when you send an article to it from the share menu.
Every path after the first is off until you turn it on. This policy describes each of them, the data the extension handles inside your browser, and the optional synchronization provided by your browser vendor.
Data The Extension Handles
StayTuned may handle the following data to provide the reader:
- Feed subscriptions: feed URL, site URL when supplied by the feed, title, category, and whether the feed is active.
- Feed content: article identifier, title, URL, publication time, summary, and author when the feed provides them.
- Feed icons: the small image a feed site serves as its icon, together with the address it came from and the time it was last checked. It is fetched from the feed site, not from any icon service, and it is not personal data.
- Reading state: read or unread state, starred or unstarred state, and the timestamps used to merge those choices between devices.
- Settings: synchronization preference, selected sync backend, refresh interval, auto-refresh preference, and interface-language preference.
- Connection secrets you enter: the Notion integration token, the identifiers of the two Notion databases, and the name, URL, and payload format of each webhook. A webhook URL is handled as a credential, because anyone holding it can post to that destination.
- Local operational state: refresh results, errors, queue depth, pending read or star changes, the record of Notion databases this device created, the Notion page-identifier cache, the outcome of the most recent webhook send, and saved article search words.
The developer cannot view this data because the extension has no service that receives it.
Where Data Is Stored
-
IndexedDB on your device stores feed content, the cached feed icons, and the local
projection of read and star state. Feed icons stay on the device that fetched them: they
are never placed in
storage.syncand are never sent to Notion, and deleting a feed deletes its icon. -
Browser extension
storage.localstores the local subscription mirror, refresh status, the outbound queue, the Notion token, the two Notion database identifiers, the record of databases this device created, the Notion page-identifier cache, your webhook list, the last webhook delivery outcome, and saved article search words. -
Browser extension
storage.syncstores your settings under every backend: the synchronization preference, the selected sync backend, the refresh interval, the auto-refresh preference, and the interface language. When synchronization is on and the browser-account backend is selected, it also stores the subscription list and quota-bounded recent read and star state.
Secrets are never written to storage.sync. The Notion token, the Notion
database identifiers, the provisioning record, and webhook URLs stay in
storage.local on the device where you entered them, so a second browser is
connected by entering them again there. That division is enforced in the code by an
allowlist rather than by convention:
extension/src/shared/sync-data-classes.ts names every value each backend may
carry, and the Notion client rejects any request naming something outside that list before
the request reaches the network.
Synchronization is off by default. When you enable it, the browser vendor may copy
storage.sync data between browser profiles signed into that vendor's account.
Chrome and Edge, Firefox, and Safari/iCloud use their own separate synchronization systems;
StayTuned does not operate or bridge them. Your browser vendor's privacy policy governs its
handling of synchronized extension storage. Article text is never placed in
storage.sync; each device fetches feeds for itself.
Feed Requests And Optional Site Access
StayTuned makes direct HTTP or HTTPS GET requests to the RSS or Atom feed URLs you add. Before the first request, it asks the browser for optional access scoped to that feed site's origin. If you deny the request, the feed remains saved but paused until you grant access. You can revoke the origin in your browser's extension settings at any time.
The feed host receives an ordinary network request and may observe information inherent in
that request, such as your IP address, request time, and browser networking headers. When
the browser allows it, StayTuned appends _StayTuned-Feed-Reader to the
browser's default User-Agent so the publisher can recognize this extension. The feed
host's own privacy policy governs that information. StayTuned does not add your settings,
subscription list, reading state, or cached articles to the request. HTTP feed requests
are not encrypted; prefer HTTPS feeds where the publisher offers them.
After a feed is fetched successfully, StayTuned looks for that feed's icon, so the feed can be shown with the publisher's own image instead of a generic symbol. One check makes up to four image GET requests, each to the feed site itself or to an address the feed itself declares, which may be a host run by somebody else. It never asks a third-party icon service. Each address is requested only when you already granted access to its origin, and skipped without any request when you did not. The requests carry no cookies and no credentials, each one is abandoned after 5 seconds, and only an image no larger than 128 KiB is accepted. The first image found ends the check, so the later addresses are usually never requested. A check is repeated at most once a week for a feed whose icon was found and at most once a day for one whose icon was not. The image is stored on your device. If no icon is found, the reader keeps showing the symbol it derives from the feed address, and nothing further is requested until the next check.
Opening an article follows its URL in a browser tab. The destination website then handles the visit under its own privacy policy, just as it would for a link opened from another page.
Finding A Feed From A Site Address
You can paste the address of a site rather than the address of its feed. The extension then asks for access to that site's origin and, only if you grant it, makes one HTTP or HTTPS GET request to the address you typed and reads the feeds that the page advertises in its markup. A denial makes no request at all.
That request abandons itself after 8 seconds, reads at most 512 KiB of the document, and sends no data of yours beyond the ordinary request the site receives from any browser, plus the same User-Agent suffix used for feed requests when the browser allows it. Nothing from the page is stored: the feed addresses it advertises are shown to you so that you can choose one, and only the feed you add is saved.
Optional Notion Synchronization
You can use a Notion workspace you own as the sync backend, so that one feed list and one set of read and star flags converge across different browser vendors instead of within one browser account.
This backend is off by default. A new installation uses the browser account, and the
extension makes no request to api.notion.com until you select Notion in
Settings, grant the optional https://api.notion.com/* host permission, and
store an integration token together with the identifiers of the two databases. The
workspace, the integration, and the token are yours; the developer has no access to them
and receives nothing from them.
What Is Sent To Notion
Requests carry your integration token in an authorization header, and write exactly these columns:
-
Subscriptions database, one row per feed:
Name, which is the feed title;Site URL;Feed URL;Category;Active; andFeed ID, the identifier the extension gave that subscription. -
Read State database, one row per article URL:
Title,URL,Read,Starred,Read At,Starred At, andItem Key. A row is written when you change read or star state, and also for locally cached articles published in the last year (the newest 10,000 distinct links), including unread and unstarred ones.Titleis the article title.URLis the canonical article link, and is the identity of the row: two feeds that publish the same link share one row.Item Keyis the 16-character hash the extension uses locally, stored last because it is not what the Notion list is for. The timestamps are numbers.
Those thirteen column names are the complete list the Notion path is permitted to name, in
a write or in a query filter. Removing a feed locally sets Active to false on
its row rather than deleting the row, so a row you want gone is deleted in Notion by you.
The extension also reads from Notion. Connecting reads the identity of your own integration, to confirm the token works, and the schema of the two databases, to confirm the columns above exist. Each later sync cycle reads the rows of those two databases, to merge what another browser wrote.
What Is Never Sent To Notion
- Article bodies, summaries, and authors. The Read State row carries the article title, the article URL, the local item hash, and the flags. It does not carry the body or any other metadata.
- Settings. The sync preference, the refresh interval, the auto-refresh preference, the interface-language preference, and the backend selection itself stay in the browser account under every backend.
- Secrets. The Notion token, the database identifiers, and webhook URLs are never written into a Notion page.
- Per-device state: fetch times, errors, the outbound queue, sync status, and the page-identifier cache.
Creating The Databases In Your Workspace
The extension can create the two databases for you rather than asking you to build them by hand. When you use that path, and only then, it asks Notion for the list of pages you shared with your integration, so that you can choose which one the databases are created inside. That list is what Notion returns for a page search, it is limited to what you shared with the integration, it is shown to you in a picker, and only the identifier of the page you choose is stored on your device. The extension then creates two databases as children of that page, with the columns named above.
If you would rather create the databases in Notion yourself and paste their identifiers, the extension reads no page list and creates nothing.
Stopping It
-
Disconnecton the Notion Integration page removes the token, both database identifiers, the record of the databases this device created, and the page-identifier cache fromstorage.local. Nothing further is sent, and the local reader keeps working. - Selecting the browser-account backend again also stops the Notion path.
-
Revoke
api.notion.comaccess in your browser's extension settings to withdraw the permission. - Your workspace keeps the databases and rows already written until you delete them, and the integration itself is removed in Notion, not in the extension.
Optional Webhook Sharing
Each article carries a share control. It offers three kinds of action, all of which you start:
-
Copy linkwrites the article URL to your clipboard. Nothing leaves the device. -
Post to Xopens a compose window athttps://x.com/intent/postwith the article title and URL filled in as parameters. Nothing is posted until you send it there, and X handles that visit under its own privacy policy. -
Send to, one entry per webhook you configured, posts the article to that endpoint.
A webhook is a URL you paste into Settings, such as a Slack or Discord incoming webhook. The extension asks for access to that endpoint's origin when you save it, and refuses to send when the access is missing. Nothing is sent to any webhook until you pick its entry for an article.
A send is a single HTTP POST with a JSON body carrying the article title, the article URL, the feed name, and the publication date. Nothing else about the article goes with it: not the summary, not the author, not your read or star state, and not your subscription list. The request carries no cookies, no credentials, and no header identifying you or the extension. It is abandoned after 10 seconds, and a failed send is reported to you once and never retried, so a share happens as many times as you ask for it and no more.
Whoever operates that endpoint receives what you sent, under their own privacy policy. Deleting the webhook in Settings stops it, and you can revoke its origin in your browser's extension settings.
Permissions
StayTuned uses these browser-extension permissions:
storagestores the data described above.alarmsschedules periodic feed refresh.-
clipboardWritelets the share menu put an article URL on your clipboard. -
sidePanelon Chrome and Edge opens the reader in the browser side panel. -
Optional access to
https://api.notion.com/*is requested only when you connect the Notion backend. It is not required at installation. - Optional HTTP and HTTPS host access lets the extension fetch the feed origins you add and approve, the site whose feed you ask it to find, and the webhook endpoints you configure. It is not required at installation.
The extension does not request access to browsing history, tabs, cookies, location, contacts, camera, microphone, or advertising identifiers.
Retention And Deletion
Data remains in browser-managed extension storage until it is replaced, evicted under the documented sync quota, removed through the reader, cleared through browser profile controls, or removed with the extension according to that browser's behavior.
You can stop future feed requests by pausing or removing a feed or revoking its optional site access. You can stop future browser synchronization by turning synchronization off. To remove synchronized copies already held by a browser vendor, use that vendor's extension-data or profile-sync controls. You can stop future Notion requests by disconnecting Notion or selecting the browser-account backend, and you delete rows already written to your workspace in Notion itself. You can stop future webhook sends by deleting the webhook. There is no StayTuned server account and therefore no server-side data-deletion request to make.
Security
StayTuned uses browser storage APIs and asks for the narrowest host access available at runtime. It does not execute remotely hosted code. HTTPS requests are encrypted in transit; HTTP feed requests are not. The Notion token and your webhook URLs are stored unencrypted in extension local storage, as browsers provide no separate secret store for extensions, which is also why neither is ever handed to browser-vendor synchronization. Anyone with access to your browser profile or browser-vendor account may be able to access data stored or synchronized by that profile.
Children
StayTuned is not directed to children and does not knowingly collect information from anyone. Feed content is selected by the user and is not moderated by the extension.
Changes To This Policy
A release that changes data handling must update this policy, the store privacy declarations, and the effective date before publication. The repository history records every version of this policy.
Contact
For privacy questions or reports, open an issue in the public project support tracker.