Privacy Policy
Last updated: September 2026
Policy Summary
Pharos does not ask for accounts. The only wallet interaction is the optional supporter API key claim on the API page, which stores a wallet address, key prefix, and claim time. Portfolio data and homepage shortcut preferences are stored locally by default, share links encode holdings in the URL, analytics are anonymized when enabled, and support or API-access requests route through the feedback/contact channels listed below. Stablecoin Picker functional browser storage and share snapshots are described below.
What We Collect
When Google Analytics 4 (GA4) is enabled, public pages on pharos.watch collect anonymized usage analytics such as page views, session duration, approximate geographic region, device or browser type, and a small set of product-interaction events. The embedded PharosWatchBot Mini App, operator pages, and preview deployments are excluded from GA4 and Web Vitals collection. If you choose to share a Telegram or X handle in the feedback form, that handle is included in the GitHub issue created for the submission. Telegram alert subscriptions store chat ID, optional username, followed coins, alert settings, quiet hours, snooze state, and an optional private-chat daily recap schedule, and short-lived pending-command or pending-alert metadata; subscriber rows with no follows or pending state and no Telegram activity for 180 days are automatically purged by a weekly cleanup job. If you request API access, Pharos stores the email address you verify plus any name, organization, project URL, use-case, intended-endpoint, cadence, and volume details you submit; request throttling stores salted hashes of IP address and user-agent data. Homepage saved shortcuts store only an ordered list of route hrefs in browser-local storage and are not sent to the API. The Stablecoin Picker stores local browser state for callout dismissal and tab-scoped result recovery, and share links can store a content-addressed snapshot of the generated selector output in Cloudflare KV.
Stablecoin Picker Storage
The Picker at /screener/picker/ uses functional browser storage. The long-lived local key in the current build is the callout dismissal key, pharos.selector.callout.v1. It is scoped to this site, does not contain an IP address or user identifier, and remains until you clear browser site data. A tab-scoped sessionStorage key, pharos.selector.sessionResult.v1, can hold the last successful live result for accidental navigation recovery and clears when the browser session ends.
Picker share links use a sid that points to a Cloudflare Pages KV snapshot of the form answers and resulting output. Snapshot IDs are content-addressed, so identical answers against an identical dataset produce the same ID. Anyone with the link can view the frozen artifact. Snapshots do not include IP addresses, browser fingerprints, or account identifiers, and expire after 90 days if never opened; the first successful read extends retention to five years.
Telegram Data and Retention
PharosWatchBot stores only what is required to deliver alerts and keep the bot reliable. Storage categories include:
- Subscribers (chat ID, optional username, default alert flags, quiet hours, snooze state, last-active timestamp): auto-purged after 180 days of inactivity once no follows, enabled daily recap, or pending state remain.
- Per-coin and preset subscriptions: live settings are retained until
/unsubscribe allor/forget. Inactivity cleanup removes only inert per-coin rows after 180 days; preset follows and meaningful per-coin settings do not expire for inactivity. - Pending disambiguation (ambiguous ticker prompts, setup wizard state, bulk-action confirmations): 5-minute TTL.
- Pending alerts (overflow and retry queue for delivery): 2-hour TTL for depeg, DEWS, safety, reserve, freeze, and legacy alerts; 90-minute TTL for launch alerts, 45-minute TTL for admin broadcasts, and 6-hour TTL for an exact personalized recap message.
- Personalized recap preferences and delivery audit: the private-chat timezone, local hour, and enabled state are retained while configured. Sent and skipped aggregate target metadata is retained for 30 days; cancelled, expired, execution-unknown, and permanently failed audit metadata is retained for 90 days. Pending message bodies follow the delivery-queue lifecycle above.
/forgetremoves the preference, target metadata, and chat-attributable pending or dead-letter rows immediately. - Alert job manifests and per-target audit: 90-day retention. A private-chat
/forgetremoves that chat's target rows and per-target item lineage, planning snapshots, rendered target plans, and transport-failure observations; aggregate job manifests remain until their normal prune. - Freeze event and recipient lineage: immutable Tape and blacklist source identities plus the one-time opt-in recipient cohort are retained for 90 days. A private-chat
/forgetremoves that chat's freeze target rows immediately; source events remain until their normal audit prune. - Dead-letter audit trail for expired or permanently failed deliveries: 90-day retention, or immediate removal for that chat through
/forget. - Processed-update idempotency claims: 7-day prune.
- Daily usage aggregates: privacy-preserving counters only; no chat ID is stored. 400-day retention.
- Daily watcher lifecycle snapshots: aggregate-only public pulse history with 400-day retention.
- Per-chat delivery diagnostics used by
/health: kept while the subscriber exists, with a 90-day stale prune.
For the PharosWatchBot Mini App, the signed Telegram initData body is never persisted. It is validated request-locally through Telegram's HMAC signature and freshness window. Mutations use a 5-minute auth window plus a bounded per-user Pharos edit budget, while read-only session and watchlist portability requests accept a Telegram-signed launch up to 24 hours old so an open panel stays usable across the day. Exported watchlist tokens and pasted import tokens are returned or decoded request-locally and are not stored as token blobs. The embedded route does not load Google Analytics or report Web Vitals. After signed authentication succeeds, the Worker records only low-cardinality daily counters for Mini App adoption, operation outcomes, and error categories; those aggregate rows contain no chat ID.
Personalized daily recaps are assembled deterministically from Pharos's existing D1 event Tape and the subscriber's current watchlist. This path makes no AI-model request and no external planning-data request, so watchlist intent and recap content are not sent to an AI provider or a separate personalization service.
Inline-mode status queries use public tracked-coin data. Pharos stores only aggregate query and selected-card counters; query text, inline query IDs, result IDs, chat IDs, and user IDs are not persisted in D1 or custom Worker logs.
The Telegram Worker also emits sampled operational logs to Cloudflare Workers Logs for reliability and incident response. Telegram-specific custom log records are limited to operation names, bounded counts, status codes, retry timing, and fixed error categories. They exclude chat and user IDs, update and callback identifiers, message or callback content, URLs, bot tokens, and Mini App initData. Cloudflare processes these records in the Pharos Cloudflare account, where access follows the account's permissions. This repository does not configure a separate Logpush archive or a Telegram-log retention duration. Per-chat incident investigation uses the private operator diagnostics backed by D1 instead of general logs.
No Accounts
Pharos does not require user accounts or logins for the website. Optional feedback contact details and self-serve API request emails are self-declared and are not used as site accounts.
The one exception is optional: the supporter API key claim on the API page asks a wallet to sign a short text message so the key can be tied to a donating wallet. Pharos stores the wallet address, the issued key prefix, and the claim time, plus the key record itself, which is named after the address and carries the last-used timestamp and route that every API key records. Those records are retained without an automatic expiry. Deactivation stops access but does not delete these records. You can request removal of the key record and its usage metadata through the feedback form. We retain the wallet address, key prefix, and claim time to prevent a second claim, unless an operator explicitly approves removing that restriction. The public donation ledger is a separate record. Signatures and plaintext API tokens are never persistently stored or logged; only a keyed hash verifies the token. An unsaved token remains in browser memory across internal navigation so you can recover it, until you copy or acknowledge it or leave or reload the site. It is never written to localStorage or sessionStorage.
Cookies
On GA4-enabled public website routes, the only cookies set by Pharos are those required by Google Analytics 4 (e.g., _ga, _ga_*) for distinguishing unique visitors. No advertising or tracking cookies are used. The embedded PharosWatchBot Mini App does not load GA4 or set GA4 cookies.
Data Retention
When GA4 is enabled, analytics retention is controlled by the externally configured GA4 property rather than guaranteed by repository code. We do not maintain user-account databases. Feedback submissions are sent to GitHub Issues for product support and issue tracking; optional follow-up contact details are included there when you provide them. The worker stores rate-limit metadata for feedback abuse prevention. The current submission path does not persist a separate D1 submission row. Self-serve API key requests are stored for operator review and duplicate-claim enforcement; verification tokens are stored only as hashes and expire after 30 minutes. Issued self-serve API keys expire after 60 days by default. Homepage shortcut preferences remain until reset or browser site data is cleared. Picker localStorage remains until browser site data is cleared. Unread Picker KV snapshots expire after 90 days; the first successful read extends retention to five years because they are content-addressed analytical records rather than user-account records.
Third-Party Services
Pharos is hosted on Cloudflare Pages with API endpoints served by Cloudflare Workers. Analytics data is processed by Google (GA4) only when analytics is enabled on the public website, excluding operator pages, preview deployments, and the embedded PharosWatchBot Mini App. Feedback submissions are also forwarded to GitHub Issues for product triage; optional Telegram/X handles are echoed publicly in those GitHub issues. API request verification emails are sent through Resend. API key issuance records stay in private operator storage and structured Worker logs; requester details and key material are not published to GitHub Issues.
Contact
Questions about this policy? Reach out on @PharosWatch or via the About page.