Skip to main contentSkip to data table
Pharos

Privacy Policy

Last updated: July 2026

Policy Summary

Pharos does not ask for accounts or wallet connections. 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 a Google Analytics 4 (GA4) measurement ID is configured for the current deployment, public Pharos website routes 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 is 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 are retained for five years.

Telegram Data and Retention

PharosWatchBot stores only what is required to deliver alerts and keep the bot reliable. The full list of Telegram-owned tables and how long each one is retained:

  • 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 all or /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. /forget removes 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 initDatabody 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 or Wallet Connections

Pharos does not require user accounts, logins, or wallet connections for the website. Optional feedback contact details and self-serve API request emails are self-declared and are not used as site accounts.

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 data is retained for 14 months per Google's default settings. 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. Picker KV snapshots are retained for 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 for the current deployment and never from the embedded PharosWatchBot Mini App route. 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.