Analyst Intelligence
Market Intelligence Platform

Welcome back

Sign in to your account to continue

Enter your email, the invite code from your welcome email, and choose a password.

Enter your email and we'll send you a 6-digit reset code.

Enter the 6-digit code sent to and choose a new password.

Submit Feedback

All feedback is reviewed personally. You'll hear back within a week.

RSS/Atom feed URL — must return XML Blog index page to scrape for article links Press release page to scrape Changelog RSS/Atom feed URL — fetched the same way as RSS

Suggested sources

We interrogated 's website and found these candidate sources. Pick the ones to add.

Interrogating website…
No blog or press sources detected automatically. You can add sources manually from the vendor's card.

Export Vendors CSV

Select the markets to include in the export. Each vendor row will include its name, website, and all configured feed sources.

No markets available

Add Market

Analyst Intelligence Analyst Intelligence

Feed

Sort by

No items yet — run ingestion and processing first

Digest

📭
No updates for this date
Nothing was tracked, or all items scored below the relevance threshold.
Powered by Claude

Ask anything about your vendors

Semantic search across every tracked announcement — get a direct answer, market context, and impact ratings in seconds.

Semantic search not enabled. Add OPENAI_API_KEY to Railway, then run Backfill Embeddings from the Admin tab.
AI analyst brief — direct answer + vendor impact ratings from Claude

Try asking about

Semantic Search
Natural language queries — finds conceptually related items even without exact keyword matches.
AI Analyst Brief
Claude synthesizes results into a direct answer, market context, and vendor-by-vendor analysis.
Impact Ratings
Every result is scored 1–100 for market impact. Analyst brief ranks vendors by significance.

Searching and generating analyst brief…

No results found — try a broader query or run backfill from Admin if items are missing

Vendors

🔧 Source Repair Suggestions ()

These sources have been dark for 7+ days. Each suggestion below was verified working (item/link count shown). Apply swaps the source URL; Dismiss keeps things as they are.

No vendors found

Markets

Define market scope to improve relevancy scoring and search quality.

No active markets found.

User Management

Invite New User
Market access

Select at least one market — users must have access to at least one market.

✓ Invite sent to

Authorized Users
No users registered yet — invite a colleague above
Send Push Notification
Send a custom notification to all registered iOS devices or specific users.
Send Notification

Vendor Discovery

Auto-detected candidate vendors awaiting your review. Approving one adds it to your vendor list; nothing is added automatically.

Schedule: Last scan: Next scan:

Discovery is running in the background. New candidates will appear here in a few minutes — use Refresh to check.

Match sensitivity
Minimum market-fit score (0–100) a candidate must reach to be staged. Lower it to surface more (looser) matches; raise it to keep only strong matches.
Loading candidates…

No candidates.

Run discovery to scan your markets for new vendors.

System Status

System Status
Live check:
Background Jobs
Service Integrations

Indicators show configuration by default; Run health check live-pings each service and overlays real status + latency. OK reachable · Down unreachable / bad key · Off optional, not configured. The Tavily ping uses ~1 credit. Source-level scrape health is in the Vendors tab.

Technology Dependencies

Third-party vendors this platform depends on — for status checks and incident triage.

Vendor Role Tier Website

Admin

Pipeline
Run steps individually or use Full Run to execute all three in sequence.
1 Ingest
Polls all vendor RSS feeds and blog pages for new content.
Schedule
Last ran
Next run
2 Process
Scores and summarizes raw items via Claude. Sends push notifications.
Schedule
Last ran
Next run
3 Send Digest
Compile and email the digest for the selected date.
Schedule
Last ran
Next run
Bi-Weekly Recap
Themes narrative, most-active vendors, and category mix for the last 14 days — one email per active market. Runs automatically on the 1st and 15th at 07:00; this button sends it now (markets with no relevant items are skipped).
Schedule
Last ran
Next run
Web Scraping
Render API configured () Render API not configured — JS-rendered & bot-blocked (403) pages can't be read

Scrapes use httpx first, then the render API (if configured), then Playwright. Set SCRAPE_RENDER_API_KEY to enable the render fallback. Check per-source reasons in the source-health panel: render_http_401/402 = bad key / out of credits, http_404 = source URL moved.

Test render (live)

Renders the URL through the actual fallback path and compares it to the static fetch. Uses ~1 render credit.

Push Notifications
APNs configured APNs not configured sandbox (Xcode) production devices registered
Set APNS_KEY_ID, APNS_TEAM_ID, APNS_BUNDLE_ID, and APNS_KEY_CONTENT in Railway to enable.
Send Custom Notification
URL Dedup Cleanup
Re-normalises all stored URL hashes (trailing slashes, http→https, case) and marks any duplicate raw items found. Run once after the May 2026 URL normalisation fix. Safe to re-run.
Configuration
✓ Saved
0 — everything 100 — nothing
Items scoring below this appear under "Also Noted" Items at or above appear as "Top Stories"
Any newly processed item in a watched category triggers a push notification right after the overnight processing run — hours before the digest email. Leave all unchecked to disable.
Case-insensitive whole-word match against each item's title, preview, captured article text, and AI summary — e.g. a product name ("Intune"), technology ("Copilot"), or company. Matching items trigger an immediate push and get a ⚑ marker in the digest. Max 50.
No keywords watched.
Semantic Search
Generate embeddings for processed items so semantic search works. Use Backfill New for routine use — skips items that already have an embedding. Use Re-embed All after switching embedding models: clears existing vectors and regenerates everything.
Relevance Feedback
No feedback recorded yet — thumbs up/down links will appear in each digest email once APP_BASE_URL is set in Railway.

Platform Documentation

Architecture, dependencies, operations guide, and cost reference for support engineers.

Contents
1 · Platform Overview

Analyst Intelligence is a private market intelligence platform that automatically monitors vendor announcements across configurable markets, scores them for relevance, and delivers a daily AI-generated digest by email and iOS push notification. It is designed to be operated by a single administrator with a small number of invited iOS users.

The platform runs a nightly three-stage pipeline: ingestion (fetch RSS feeds and scrape vendor websites), processing (deduplicate, prefilter, and score each item with Claude AI), and digest (compile, summarize, and deliver). Users access content via a web dashboard (API key auth) or the native iOS app (email/password JWT auth).

FastAPI
Backend
SwiftUI
iOS App
Claude Haiku
AI Engine
2 · System Architecture
┌──────────────────────────────────────────────────────────────────┐
│                        RAILWAY (Cloud Host)                       │
│                                                                    │
│  ┌──────────────────────────┐   ┌────────────────────────────┐   │
│  │   FastAPI + Uvicorn      │   │   PostgreSQL (Railway DB)   │   │
│  │   (Python 3.12)          │◄──►  14 tables, ORM via         │   │
│  │                          │   │   SQLAlchemy 2.0            │   │
│  │  ┌────────────────────┐  │   └────────────────────────────┘   │
│  │  │  APScheduler       │  │                                    │
│  │  │  02:00 Ingestion   │  │   ┌────────────────────────────┐   │
│  │  │  04:00 Processing  │  │   │   Static Files             │   │
│  │  │  HH:MM Digest      │  │   │   dashboard.html           │   │
│  │  └────────────────────┘  │   │   about / support / privacy│   │
│  └──────────────────────────┘   └────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────┘
         │                  │                    │
         ▼                  ▼                    ▼
  ┌─────────────┐   ┌──────────────┐   ┌──────────────────┐
  │  Anthropic  │   │    Resend    │   │  Apple APNs      │
  │  Claude API │   │  Email API   │   │  Push Service    │
  │  (Haiku)    │   │              │   │                  │
  └─────────────┘   └──────────────┘   └──────────────────┘
         ▲                                       ▲
         │                                       │
  ┌──────────────────┐              ┌────────────────────┐
  │  Web Dashboard   │              │   iOS App          │
  │  Alpine.js +     │              │   SwiftUI          │
  │  Tailwind CSS    │              │   JWT + Keychain   │
  │  (API Key auth)  │              │   (email/pw auth)  │
  └──────────────────┘              └────────────────────┘
3 · Backend

Framework & Server

FastAPI 0.115.5 served by Uvicorn 0.32.1 (ASGI, HTTP/2). Entry point: backend/app/main.py. On startup the app initialises the database schema, starts APScheduler, and registers all API routers.

Database

PostgreSQL via SQLAlchemy 2.0 ORM (psycopg2-binary driver). Schema management uses idempotent SQL fixups that run on every startup — no Alembic migrations. Connection pool: size 5, max overflow 10.

Authentication

Web dashboard: static X-API-Key header matched against the API_KEY environment variable using hmac.compare_digest() (timing-safe).

iOS app: JWT Bearer token (HS256, 30-day expiry) issued on email + password login. Password hashed with bcrypt. One-time invite and reset codes stored as SHA-256 hashes in auth_tokens. Signature and expiry are explicitly enforced on every decode. All auth events (login, activation, password reset — success and failure) are logged with the source IP address. The JWT_SECRET is validated at startup; the server refuses to start if it is still the placeholder default.

Security Hardening

CORS: Locked to https://www.analystintelligence.ai with an explicit allowlist of methods (GET POST PATCH DELETE) and headers. The iOS app communicates via Authorization: Bearer directly and is unaffected by browser CORS.

HSTS: Every response includes Strict-Transport-Security: max-age=31536000; includeSubDomains. After one visit, browsers permanently refuse to connect over plain HTTP.

Error messages: Internal infrastructure details (platform names, environment variable names, exception text) are logged server-side only. HTTP error responses return generic messages.

Additional hardening (April 2026): Auth endpoints are rate-limited via slowapi (login: 5/15 min; forgot-password: 3/hr; set-password: 10/hr; reset-password: 5/hr). The web dashboard JWT is stored in an httpOnly SameSite=Lax cookie — no longer in localStorage — eliminating XSS token theft. Admin routes use a centralized require_admin dependency. POST /auth/logout clears the cookie server-side. JWT lifetime shortened to 7 days (was 30) to reduce the exposure window from stolen tokens. Password policy raised to 12+ characters with uppercase, lowercase, digit, and special character required. Vendor and source URLs are validated to only accept http:// or https:// schemes on create/update. User role is now read from the server via GET /auth/me on every page load — auth_role is no longer stored in localStorage, eliminating the ability to escalate the visible UI role by editing browser storage. The iOS app is unaffected — it continues to use Authorization: Bearer headers with tokens stored in Keychain. Remaining known risks: no server-side JWT revocation (a revoked token remains valid until its 7-day expiry); no TOTP/2FA.

Scheduler (APScheduler 3.10.4)

02:00 Ingestion — fetches all active RSS feeds (feedparser) and scrapes blog/press pages (Playwright + BeautifulSoup4). Stores raw items; deduplicates by URL hash.
04:00 Processing — fuzzy title dedup (rapidfuzz), keyword prefilter (removes job postings, awards, etc.), Claude Haiku LLM analysis per item.
HH:MM Digest — compiles items, generates executive summary, sends email via Resend, sends iOS push via APNs. Time is admin-configurable; changes take effect immediately without restart. The job has a 30-minute misfire_grace_time — if the service restarts within 30 minutes of the scheduled time the job fires immediately on startup. Email recipients are derived from user accounts — admin users receive every market's digest; role=user accounts receive only the markets in their access list. Only active users who have completed account setup (password set) are included. No separate email list is maintained.

AI Usage (Claude Haiku for processing & summaries · Claude Sonnet for search)

Item Scoring & Summarization

Each passing item is sent to Claude with its title, first 600 characters of content, vendor name, and market context. Claude returns a JSON payload with: relevance_score (0–100), category, headline (≤15 words), summary (2–3 sentences), why_it_matters (1 sentence), and confidence. Calibrated with few-shot examples drawn from user thumbs-up/down feedback. Max 512 output tokens.

Executive Summary

Generated once per digest at compile time, stored in the digests.exec_summary column. Claude receives the top-scored items grouped by vendor and writes a ≤250-word analyst brief with vendor names bolded and one paragraph per vendor. Included in email, web dashboard, and iOS app.

Search Summarization claude-sonnet-4-6

Optional. Uses Claude Sonnet (claude-sonnet-4-6) rather than Haiku — the richer synthesis across many results benefits from the stronger model. When a user submits a search query with summarize=true, the top 12 results are sent to Claude which returns a structured AnalystBrief: direct_answer, market_context, per-vendor vendor_analyses with impact ratings, and strategic_takeaway. 90-second timeout. Requires OPENAI_API_KEY for embeddings.

Python Dependencies

Package Version Purpose
4 · Web Frontend

Single-page application served as a static HTML file (backend/app/static/dashboard.html). No build step — all dependencies loaded from CDN.

Alpine.js 3.14.1

Lightweight reactive framework. All state lives in a single app() function. No build tooling or bundler required.

Tailwind CSS (CDN)

Utility-first CSS. Dark mode enabled via darkMode: 'class'. The .dark class is applied to the authenticated app container and each modal individually (not <html>), keeping the login page permanently light. Toggle preference stored in localStorage. All type="date" inputs require explicit dark:bg-slate-700 dark:text-gray-100 classes — the browser's native date picker does not inherit color-scheme automatically from Tailwind.

Inter (Google Fonts)

Primary typeface. Loaded from fonts.googleapis.com. Free, no API key required.

Authentication

API key entered at login; verified against GET /markets/ before granting access. Stored in memory only (no persistence after refresh).

Tabs

5 · iOS Application

Native SwiftUI app (ios/AnalystIntelligence/). No third-party Swift packages — uses only Apple system frameworks (Foundation, UIKit, SwiftUI, UserNotifications, Security). Requires iOS 16+ and an Apple Developer account for distribution.

Authentication Flow

Admin registers user via the web dashboard → system emails an 8-character invite code → user opens app, enters invite code + sets password → POST /auth/set-password returns JWT → token stored in iOS Keychain → all API calls include Authorization: Bearer <token>. JWTs expire after 30 days; user must re-login.

Key Files

File Purpose

Push Notifications (APNs)

Device tokens registered via POST /devices/register on every app launch. Digest job pushes via Apple APNs using HTTP/2 + JWT authentication (requires APNS_KEY_ID, APNS_TEAM_ID, APNS_BUNDLE_ID, APNS_KEY_CONTENT).

Set APNS_SANDBOX=true for Xcode debug builds; false for TestFlight/App Store. When switching environments, use Admin → Clear Device Tokens to purge stale registrations.

6 · Data Pipeline
1
Ingestion (02:00)

Iterates all active vendor_sources rows. RSS / release-notes sources parsed with feedparser (24-hour lookback). Blog and press scrape sources use a tiered fetch — httpx + BeautifulSoup first, then an optional hosted render API for JS-rendered SPAs, then a shared Playwright/Chromium browser — to extract article links. Each new URL is stored as a RawItem with a URL hash for deduplication. A fetch that yields zero links is recorded as a failure with a reason (zero_links, http_404/403, fetch_error) so broken sources surface in source health; counts reset on success. At processing time the pipeline also performs full-text capture: the article body is fetched (static, SSRF-guarded), stored on the item (up to 20k chars) for archive durability and search, and a 1,500-char excerpt is fed to Claude for scoring. Sources dark for 7+ days are re-probed by the daily Source Repair job (03:30), which stages verified replacement URLs in the Vendors tab for one-click Apply/Dismiss.

2
Processing (04:00)

Unprocessed RawItems pass through three gates: (a) fuzzy dedup — rapidfuzz title similarity against recent items; (b) keyword prefilter — rejects job postings, award announcements, speaking engagements, and customer case studies; (c) LLM analysis — Claude Haiku scores relevance (0–100) and generates headline, summary, why-it-matters, and category. Items scoring at or above the Relevance Threshold are flagged in_digest=true.

3
Digest Compilation

Groups in_digest=true items by market and date. Items scoring ≥ Top Story Threshold appear under "Top Stories"; items between the two thresholds appear under "Also Noted". Claude generates a per-market executive summary stored in digests.exec_summary. Compilation is idempotent — re-running does not regenerate the exec summary if it already exists. Vendor priority tiers shape the digest: high-tier vendors get a +5 relevance boost at processing time and sort first; low-tier vendors never appear as Top Stories (Also Noted only). Tiers are set per vendor in the Vendors tab.

4
Delivery (configurable time)

HTML digest email rendered per market and sent via Resend to configured recipients. Apple APNs push sent to all registered device tokens. Both delivery methods record a sent_at timestamp on the Digest row. The email also includes an Activity Spikes section when any vendor posts at 3×+ its normal weekly cadence, a Source Health section whenever any of the market's active sources has had no successful fetch for 7+ days, and zero-item ("quiet day") digests carry a coverage line — items collected and sources checked — confirming the pipeline ran normally. Separately, watched categories and watch keywords (Admin → Configuration) trigger an immediate push notification for any newly processed matching item right after the overnight processing run; keyword matches additionally carry a ⚑ marker in the digest email, and pending source-repair suggestions are counted in the Source Health block.

Scoring Thresholds

0 ──────────── [Relevance Threshold] ──── [Top Story Threshold] ──── 100
0–threshold: excluded threshold–top_story: Also Noted top_story–100: Top Stories

Both thresholds are configurable in Admin → Configuration. Default: Relevance = 45, Top Story = 70.

7 · Vendor Discovery

Vendor discovery automatically finds candidate vendors for each market so you don't have to add them by hand. It runs weekly (Monday 03:00) and on demand from the Discovery tab. Candidates are always staged for review — discovery never adds a vendor automatically.

1
Gather & qualify

Candidates come from a Tavily search of the market definition (set TAVILY_API_KEY) and an LLM pass that mines already-ingested items for competitor mentions. Each is deduped against existing vendors (domain + fuzzy name) and scored for market fit by Claude Haiku against the market's mandatory features. Candidates below the match sensitivity (fit threshold) are discarded.

2
Detect feed URLs

For each candidate, the vendor's homepage navigation is inspected to find its blog and press/newsroom index URLs (mined candidates without a site first have their website resolved via search). The detected URLs show on every candidate card and in the admin email summary.

3
Review & approve

Pending candidates appear in the Discovery tab with fit score, confidence, evidence, and detected URLs. Approving creates the vendor and auto-configures the blog/press URLs as blog_scrape / press_scrape sources, so the vendor immediately joins the ingestion → digest pipeline. A per-market summary email is sent to that market's newsletter recipients when new candidates are staged (suppressible on manual runs).

Match sensitivity is editable at runtime in the Discovery tab (stored in app_config.discovery_fit_threshold, default 60) and is separate from the article-relevance threshold. Review directories (G2, Capterra) are not scraped for candidates — discovery uses the licensed search API plus already-ingested content.

8 · Environment Variables

Set in Railway's Variables panel (or a local .env file for development). Changes require a service redeploy to take effect, except for digest time/timezone which can be updated live via the admin settings API.

Required

Variable Description

Optional

Variable Default Description
9 · Deployment

The platform is hosted on Railway. The repository root contains a backend/railway.toml that Railway reads automatically.

Build

Nixpacks — auto-detects Python, installs requirements.txt, runs Playwright browser install.

Start Command

uvicorn app.main:app --host 0.0.0.0 --port $PORT

Health Check

GET /health — returns {"status":"ok"}. 30-second timeout. Railway restarts on failure (max 3 retries).

Schema Migration

SQLAlchemy create_all() + manual fixups run on every startup. Safe to redeploy at any time.

iOS Build

Before building in Xcode, update the backend URL in ios/AnalystIntelligence/Config.swift. No Swift Package Manager dependencies — standard library only. Requires an active Apple Developer account ($99/year) for distribution via TestFlight or the App Store.

When switching between sandbox (Xcode) and production (TestFlight) APNs environments, clear all device tokens from Admin → Test & Notifications → Clear Device Tokens to avoid silent delivery failures.

10 · Admin Operations Guide

Adding a Vendor

Go to Vendors → Add Vendor. Enter the name, website URL, and select the market. Then expand the vendor row and add at least one Feed Source. RSS and Release Notes are the most reliable source types — both fetch a standard RSS/Atom feed URL. Blog Scrape and Press Release Scrape use Playwright and require a URL pointing to the index page, not an individual post. Monitor the source health dot (green = healthy, red = one or more failures).

Running the Pipeline Manually

In Admin → Pipeline & Jobs, run steps in order: Ingestion → Processing → Digest. Each button is disabled while the job is running. Use "Run Full Pipeline" to run all three in sequence. After ingestion, check source health for any newly-failed sources before proceeding. Each job's schedule, last-run, and next-run are shown here and at GET /admin/schedule. A fifth job, the Bi-Weekly Recap (1st and 15th at 07:00), emails a per-market rollup of the last 14 days — AI themes narrative, most-active vendors, and category mix — and can be sent on demand with POST /admin/send-recap or the Send Recap Now button.

Running Vendor Discovery

In the Discovery tab, click Run discovery to scan all markets on demand (it also runs weekly, Mon 03:00). Uncheck "Email newsletter recipients" to scan without alerting subscribers. Review pending candidates and Approve (creates the vendor and auto-configures its detected blog/press sources) or Reject. Adjust Match sensitivity to surface more or fewer candidates. The panel shows the last scan and next scheduled scan. Requires TAVILY_API_KEY for the search channel; item-mining works without it.

Resending a Digest

Send Digest automatically resets before compiling — it deletes any existing digest rows for the selected date and clears in_digest flags so items are re-evaluated from scratch. Simply pick a date and click Send Digest; no manual reset step is needed.

Adding an iOS User

Go to Admin → Authorized Users → Register. Enter the user's email and role (Admin or User). If Role = User, select which markets they can access. The system emails an invite code to the address. The user opens the iOS app, taps "First time? Set up your account", enters the code and chooses a password. Invite codes expire after 7 days; use Resend Invite if needed.

Adjusting Relevance Thresholds

In Admin → Configuration: Relevance Threshold is the floor — items below this score are excluded from the digest entirely. Top Story Threshold determines the cut between "Top Stories" and "Also Noted" — must be set higher than the relevance threshold. Changes apply to new digest compilations; reset and recompile a date's digest to apply retroactively.

Market Context

Go to Markets and expand a market to edit its AI context fields: Market Definition (what the market is), Market Purpose (why users care), Mandatory Features (required product capabilities), Optional Features (nice-to-have capabilities). These fields are injected directly into the Claude prompt for every item in that market — better context = more accurate relevance scoring.

Semantic Search Setup

Search requires an OpenAI API key (OPENAI_API_KEY environment variable). After setting the key and redeploying, run Admin → Backfill Embeddings once to generate vectors for all existing processed items. New items are embedded automatically during the processing job.

11 · Third-Party Services & Cost Estimate

Estimates based on a typical deployment monitoring ~20 vendors across 2 markets, processing ~50 items per day, with 2–3 iOS users. Prices as of mid-2026 — verify current pricing with each provider.

Service Purpose Pricing Model Est. Monthly Paid?
Estimated Total ~$26 – $44 / mo
Cost scaling note: Claude API costs scale with the number of items processed per day. If you add many more vendors or markets the monthly Claude cost will increase roughly linearly. The most effective lever for controlling cost is the keyword prefilter (which blocks obvious non-relevant items before they reach Claude) and a well-tuned Relevance Threshold. Railway costs may increase if PostgreSQL storage grows significantly or if the app receives heavy traffic.

Changelog

A plain-English record of what has changed in each release, newest first.

Jul 7, 2026
Bug Fix

Mobile web navigation fixes. On phones the navigation menu is now a slide-out drawer opened from a menu button in the top header, giving access to every section — including admin-only pages like Markets, Discovery, Status, and Documentation that the old 5-item bottom bar left unreachable. The menu now scrolls, so all items are usable in landscape on short screens where the list previously ran off the bottom with no way to reach the lower entries. Tapping a destination or the dimmed backdrop closes the drawer. The tablet and desktop sidebar are unchanged.

Jul 6, 2026
Feature iOS

Face ID sign-in and smoother session expiry. When an authenticated request returns 401 (expired JWT), the app now signs out softly — keeping the account email — and returns the user to the sign-in screen with a "session expired" notice instead of surfacing raw errors in whatever tab was open. A new Sign in with Face ID toggle in Preferences (Security section) stores the password in the device keychain after a one-time verification against the server plus a biometric confirmation; from then on, expired sessions auto-offer Face ID for a one-glance re-login, and the login screen shows a Face ID button. Touch ID is used on devices without Face ID. Manual sign-out still wipes all stored credentials, and a stale stored password (changed elsewhere) disables the toggle automatically. Adds NSFaceIDUsageDescription to the app's Info.plist.

Jul 6, 2026
Bug Fix

Fixed the vendor-candidate discovery email. The "Review candidates" button now links to the web dashboard on the public site (new SITE_BASE_URL setting, default analystintelligence.ai) instead of the raw Railway service URL — which also used a broken /dashboard.html path. The notice is now sent only to admin users: candidate review is an admin-only function, so non-admin recipients previously landed on an access error. The email footer explains why the recipient is receiving it.

Jul 4, 2026
Feature iOS

Preferences tab. A new Preferences tab in the iOS app (under More) gathers app settings in one place. Open on launch selects the starting screen: Feed (default), Morning Triage, Digest, Search, or Notifications — choosing Morning Triage opens the review deck automatically on every cold start, so the ritual becomes: open app, swipe through the deck, done. Appearance sets System / Light / Dark mode. Notification settings (per-market mutes and quiet hours) are reachable from Preferences as well as the Notifications tab. Push deep-links still take priority over the launch preference.

Jul 4, 2026
Feature iOS

Four iOS additions. Home-screen widget — today's item count (small) plus the top story (medium), fed by an App Group snapshot the app writes when the digest loads; requires a one-time widget-extension target setup in Xcode (see ios/WIDGET_SETUP.md). Morning Triage — a card-deck review of the last day's relevant items: swipe right to save, left to dismiss, tap to read, with undo; reviewed items stay out of the deck for the day. Audio briefing — the Digest tab reads the day's digest aloud with on-device speech (exec summary, top stories, also-noted), with pause/stop controls. Watch-from-reader — admins can add watch keywords from any item's ⋯ menu and change vendor priority tiers by long-pressing in the Vendors list. Help topics updated to cover all four.

Jul 4, 2026
Feature iOS

Help & What's New in the iOS app. A new Help tab documents every feature — feed, reader view, saved items, digests, recaps, search, notifications, watchlists, vendors, and relevance feedback. A What's New screen summarizes each release and appears automatically the first time the app opens after an update; it's also always available at the top of the Help tab. Release notes are served from a new machine-readable endpoint (GET /changelog), so backend-only releases reach app users without an App Store update. Maintenance note: new releases must add an entry to both this Changelog tab and the structured changelog list in the backend.

Jul 4, 2026
Feature iOS

Three additions. Recap archive — bi-weekly recaps are now persisted server-side and browsable in the iOS app (calendar icon in the Digest tab): themes narrative, most-active vendors, category mix, and highlights for every past period. Feed swipe actions — swipe a feed card right to save/unsave it, left for relevant / not-relevant feedback, matching the thumbs buttons. Notification preferences — a settings screen in the Notifications tab (gear icon) lets each user mute pushes per market and set quiet hours in their local timezone; the push senders honour both. Digest emails are unaffected by mutes and quiet hours. New endpoints: GET /recaps, GET/PUT /me/notification-prefs.

Jul 4, 2026
Feature iOS

iOS reading bundle. In-app reader view — tapping a feed or saved item now opens a full reader screen showing the captured article text (from v0.59 full-text capture) without leaving the app; items without captured text fall back to a "Read original" link. Push deep-linking — tapping a watched-keyword or watched-category push opens the reader for that exact item instead of just launching the app. Watched-keyword badges — items matching your keyword watch list now show an orange ⚑ badge on feed cards and in the reader. Backend adds one endpoint: GET /feed/{item_id}/content.

Jul 4, 2026
Feature

Three additions. Keyword watchlists — add watch terms in Admin → Configuration (product names, technologies, companies); matching items trigger an immediate push and carry a ⚑ marker in the digest email, matched case-insensitively against title, preview, captured article text, and AI summary. Full-text capture — the processing pipeline now fetches and stores each announcement's article body (up to 20k chars), protecting the archive against vendor-site link rot, and feeds a 1,500-char excerpt to Claude for noticeably better scoring and summaries. Dark-source auto-repair — a new daily 03:30 job re-probes the website of any vendor whose source has been dark for 7+ days and stages verified replacement URLs; suggestions appear at the top of the Vendors tab with one-click Apply / Dismiss, and the daily digest notes when repairs await review. Nothing is changed without your approval.

Jul 4, 2026
Feature

Four additions. Bi-weekly market recap — a new scheduled job (1st and 15th at 07:00) emails a per-market recap of the last 14 days: an AI themes narrative, most-active vendors, category mix, and highlights; also sendable on demand from Admin → Pipeline & Jobs. Watched-category push alerts — pick categories to watch in Admin → Configuration (e.g. Acquisition / M&A) and any newly processed item in one of them triggers an immediate push after the overnight run, capped at 10 per run. Activity Spikes — the daily digest flags vendors posting at 3× (or more) their normal weekly cadence, often the first sign of a launch cycle. Vendor announcement history — the iOS vendor detail sheet gained an Announcement History view: the full reverse-chronological record of everything collected for that vendor.

Jul 4, 2026
Feature

Five additions in one release. Vendor priority tiers — mark any vendor High / Normal / Low in the vendor form; High vendors get a +5 relevance boost and sort first in the digest, Low vendors only ever appear under Also Noted. Bookmarks — iOS users can save items (bookmark icon on feed cards) to a server-side Saved list that survives the 7-day cache and app reinstalls. Digest Source Health alerts — the daily email now flags any source with no successful fetch for 7+ days, so a silently broken scraper is visible without opening the dashboard. Quiet-day coverage stats — zero-item digests report how many items were collected and sources checked, distinguishing "nothing announced" from "pipeline broken". Full archive in iOS — the Feed tab now scrolls back through the entire item archive with automatic paging instead of stopping at the first 50 items.

Jul 4, 2026
Security

Strengthened email feedback links: tokens now carry an issued-at timestamp and expire after 90 days (the "Link expired" page is now accurate), use the full SHA-256 signature instead of a truncated 64-bit one, and are signed with a key domain-separated from the API key (set FEEDBACK_HMAC_SECRET to fully decouple). Also upgraded the untrusted-content parsing stack — lxml 5.3.0 → 6.1.1 and Playwright 1.49.0 → 1.61.0 — which parse and render arbitrary vendor web pages.

Jul 4, 2026
Security

Hardened server-side URL fetching. TLS certificate verification is now enabled on all outbound scrape/discovery requests (previously disabled), and every fetch of a user- or vendor-supplied URL — Add-Vendor source suggestion, homepage detection, and the Admin Test render tool — now runs through an SSRF guard that rejects private, loopback, and cloud-metadata (169.254.169.254) addresses and re-checks every redirect hop. Also made JWT_SECRET a required environment variable so the app fails closed if it is ever unset, rather than falling back to a known placeholder.

Jul 4, 2026
Security

Closed a stored XSS hole in the digest Executive Summary. That summary is generated by the LLM from scraped vendor content, and it was previously rendered as raw HTML — so a malicious vendor page could have injected script that ran in the admin's authenticated session. The summary is now HTML-escaped before formatting, with only intended **bold** and line breaks re-applied.

Jun 24, 2026
Fix

An RSS source pointed at a plain HTML page (a page with no feed) now fails cleanly with "URL is not an RSS/Atom feed?" instead of throwing an unhandled error. Reminder: the render-API fallback only applies to Blog Scrape / Press Release Scrape sources — RSS / Release Notes sources are parsed by feedparser and never use rendering, so an HTML blog page must be added as a Blog Scrape source, not RSS.

Jun 24, 2026
Feature

Added a Test render tool to the Web Scraping card (Admin) that validates the render-API fallback end to end. Enter a URL and it renders it through the actual fallback path, reporting whether rendering is configured, the render status, bytes returned, and a static-vs-rendered link comparison with sample titles — so you can confirm rendering genuinely works, not just that the key is present. (The health check only validates the key.) Uses ~1 render credit per test.

Jun 24, 2026
Fix

Fixed the health check reporting Anthropic and Resend as Down when they're actually up. Anthropic now uses a direct GET /v1/models call (no SDK dependency). For Resend, a valid sending-only API key returns a "restricted" 401 on the domains endpoint — that means the key is good and the service is reachable, so it's now treated as OK rather than Down.

Jun 24, 2026
Improvement

Reorganized the navigation. System Status (the status panel, live health check, and Technology Dependencies) is now its own Status tab instead of being buried in Admin. The sidebar gained a grouped System section linking Status, Documentation, and Changelog together. The Admin tab now focuses on pipeline runs and configuration.

Jun 24, 2026
Feature

Added a Run health check button to the System Status panel that live-pings every service — PostgreSQL (SELECT 1), Anthropic, Resend, Tavily, the render API (ScrapingBee usage), and OpenAI — and overlays the real OK / Down status with response latency, plus a last-checked timestamp. Until you run it, the indicators show configuration status. The Tavily ping uses ~1 search credit; APNs is reported from config (no cheap live ping).

Jun 24, 2026
Feature

Added a System Status panel at the top of Admin that monitors every core component at a glance: all four background jobs (ingestion, processing, discovery, digest) with schedule and last-run, plus every service integration (PostgreSQL, Anthropic, Resend, Tavily, render API, OpenAI, APNs) with an OK / Off / Down indicator. Added a Technology Dependencies reference card listing each third-party vendor with its role, tier, and website/status-page links. /admin/settings now reports a configured flag per integration, and ARCHITECTURE.md was refreshed (three-tier scraper extraction, source suggestions, full component monitoring).

Jun 24, 2026
Feature

Adding a vendor with a website now auto-suggests its blog and press sources. After you save the vendor, it interrogates the site, detects the blog and press/newsroom pages, and shows them with a count — preferring a clean RSS feed (with its item count) and falling back to a scrape (with its link count). Check the ones you want and they're added as sources; a note confirms ingestion will run at the next scheduled run. No more hunting for feed URLs by hand.

Jun 24, 2026
Improvement

Added a heading-anchored extraction fallback to the scraper for blog/press pages where the title lives in a heading and the link is a separate element (e.g. a "Read more" button), or where the article URLs sit at a path unrelated to the listing page (e.g. a press page at /about-us/news-press linking to articles at /news/<slug>). It pairs each heading with its nearest same-site article link and excludes external, nav, header, and footer links — recovering vendor press pages that previously returned zero links.

Jun 24, 2026
Fix

Fixed a foreign-key error when deleting a vendor. Vendor deletion didn't clean up two newer related tables, so the delete failed for: vendors promoted from discovery (the candidate_vendors.promoted_vendor_id link) and vendors whose items had thumbs-up/down feedback (item_feedback). Deletion now clears item feedback before removing processed items, and unlinks the discovery candidate (kept as an audit record). Verified with foreign keys enforced.

Jun 24, 2026
Fix

The scraper no longer uses a URL/path as an item title. Some JS-rendered pages ship anchors whose visible text is just the slug placeholder (e.g. /blog/the-importance-of-…) before client-side hydration; these were being captured as garbage-titled items. They're now rejected, which also makes such JS-only pages correctly report zero_links rather than emitting junk. Real titles on server-rendered pages are unaffected.

Jun 24, 2026
Fix

Fixed a 400 error when adding a Release Notes source. The source-creation endpoint still validated against the old type list (rss | blog_scrape | press_scrape) and rejected release_notes — even though the dropdown, ingestion, and source health all support it. Release Notes sources can now be added (e.g. a vendor changelog RSS feed like getprimo.com/changelog/rss.xml). Also added the Release Notes label to the vendor CSV export.

Jun 24, 2026
Fix

Extended the scrape link-extraction fallback to handle a singular/plural mismatch between the listing URL and the article URLs — e.g. a blog index at /blogs whose posts live at /blog/<post> (rezolve.ai). The fallback now also matches a singular/plural sibling of the listing's section, while still excluding unrelated sections, nav, category, and footer links.

Jun 24, 2026
Fix

Fixed blog/press scrapes that returned zero links on modern site builders (Webflow, Framer, headless CMS). The scraper only recognized semantic markup (<article>, .post, h2 a…), so card-based layouts (e.g. getprimo.com/blog) matched nothing and were recorded as failures. Added a URL-structure fallback: when no semantic selector matches, the scraper collects same-site links whose path sits under the listing page (/blog/<post>), excluding nav/header/footer so menu and category links don't leak in. This also runs on the JS-rendered (Playwright) path. Note: pages returning HTTP 403 (bot-blocked) or 404 (moved URL) are a separate issue — 403s need the hosted render API enabled; 404s need the source URL updated. Admin → now shows a Web Scraping status card indicating whether the render API is configured (and which provider), so you can confirm the SCRAPE_RENDER_API_KEY fallback is actually live.

Jun 24, 2026
Improvement

Vendor discovery now appears in status reporting: the discovery job shows its schedule, last scan, and next scan in /admin/schedule and on the Discovery panel, with last-run persisted across restarts. Documentation was brought up to date — the in-app Docs tab gained a Vendor Discovery section plus updated pipeline, environment-variable, operations, and cost references, and ARCHITECTURE.md now reflects the live system (discovery subsystem, status reporting, current scraper, and costs).

Jun 24, 2026
Improvement

Candidates discovered by mining existing items (which arrive with just a company name) now get their website resolved automatically via search before the blog/press scan — so they too get their feed URLs detected and auto-configured on approval, just like search-discovered vendors. Once a site is resolved, the candidate is re-checked against existing vendors by domain to avoid adding a duplicate under a different name.

Jun 24, 2026
Feature

Discovery now detects each vendor's blog and press/newsroom URLs from the homepage navigation. The detected URLs show on every candidate card and in the admin email summary. When you approve a candidate, those URLs are automatically configured as blog and press scrape sources, so the new vendor immediately joins the feed and newsletter pipeline — no manual source setup needed. URLs that can't be detected are flagged "not detected" so you can add them by hand.

Jun 24, 2026
Feature

Added a Match sensitivity control to the Discovery panel — the minimum market-fit score (0–100) a candidate must reach to be staged for review. This is now a separate, runtime-editable threshold from the article-relevance threshold, so you can loosen vendor matching (lower the number to surface more candidates) without affecting digest scoring. Saved instantly and applied to the next scan; defaults to 60.

Jun 24, 2026
Improvement

The Discovery tab now has an "Email newsletter recipients about new candidates" checkbox next to Run discovery. Leave it on for the normal behavior; uncheck it to run a scan without alerting subscribers (useful for ad-hoc or test runs). The scheduled weekly scan always sends notifications.

Jun 24, 2026
Feature

Added a Discovery admin tab with a review queue for auto-detected candidate vendors. Run a scan on demand, filter by pending/approved/rejected, and see each candidate's market-fit score, confidence, evidence, and source. Approve adds the vendor to your list; Reject dismisses it — nothing is added automatically, and a badge shows the pending count. Discovery also now emails a market's newsletter recipients a single summary whenever a scan surfaces new candidates, clearly flagged as pending review.

Jun 24, 2026
Feature

Added automatic vendor discovery (scaffold). A weekly job — and an on-demand admin endpoint (POST /admin/discovery/run) — finds candidate vendors for each market from two channels: a Tavily search of the market definition (set TAVILY_API_KEY to enable) and an LLM pass that mines already-ingested items for competitor mentions. Candidates are deduped against existing vendors, scored for market fit by Claude Haiku using the market's mandatory-features context, and staged in a review queue. Nothing is added to your vendor list automatically — discovery only ever proposes; approving a candidate (POST /admin/discovery/candidates/{id}/approve) is what creates the vendor. Tunable via DISCOVERY_FIT_THRESHOLD.

Jun 23, 2026
Feature

Added a Vendor filter to the Feed on both the web dashboard and the iOS app. Pick a single vendor to narrow the feed to just their items; it works alongside the existing market, category, and score filters. The vendor list shows every vendor you have access to.

Jun 23, 2026
Fix Feature

Fixed silent scrape failures. A blog/press page that returned zero article links — because it moved (404), blocked us (403), or is JavaScript-rendered — was being recorded as a successful check, so broken sources never showed as failing and never auto-disabled. Zero-link scrapes now count as failures, increment the failure counter, and surface their reason (zero_links, http_404, http_403, fetch_error) in the source health panel. Also added an optional hosted rendering-API fallback (ScrapingBee / Firecrawl / Browserless / custom, configured via SCRAPE_RENDER_API_KEY) so JavaScript-rendered vendor pages can finally be read.

May 5, 2026
Fix

Fixed FK violation in Dedup Cleanup — digest item rows referencing processed items are now deleted first before the processed items themselves, preventing the constraint error on cleanup runs.

Apr 30, 2026
Feature

Added Release Notes as a new vendor source type. Works identically to RSS — point it at a vendor's changelog RSS/Atom feed and it will be ingested and scored alongside blog posts and press releases. Release Notes sources show a distinct amber badge in the source health panel and vendor list.

Apr 30, 2026
Fix Improvement

Full Run now truly waits for each pipeline step to finish on the backend before starting the next — previously the step sequence was fire-and-forget. The digest step in Full Run always targets today's date and auto-resets the existing digest before recompiling. Fatal errors in any background job (ingestion, processing, digest) now trigger an immediate alert email to the admin.

Apr 30, 2026
Improvement

Send Digest now auto-resets before compiling, so there's no longer a need to click Reset Digest first. The Reset Digest button has been removed from the admin panel. The backend deletes any existing digest rows for the target date and clears in_digest flags before recompiling, making every Send Digest idempotent.

Apr 30, 2026
Fix

Fixed scraper process exhaustion on Railway. Blog and press scrape sources were each launching a fresh Chromium browser process, hitting the container's process limit (EAGAIN) after a handful of sources. The ingestion pipeline now launches a single shared browser once per run and routes all scrape sources through it sequentially, reducing Chromium process spawns from N (one per source) to 1.

Apr 24, 2026
Feature iOS

iOS feedback submission. A feedback button (conversation icon) in the Vendors tab toolbar opens a native sheet with subject and message fields. Submitting POSTs to POST /app-feedback with source: "ios", shows a success confirmation, and appears alongside all other submissions in the web admin Feedback tab.

Apr 24, 2026
Feature

Vendor CSV export. A new Export CSV button in the Vendors tab opens a market selection dialog pre-populated with all markets you have access to. After confirming your selection the browser downloads a vendors.csv file containing each vendor's market, name, website, and all configured feed sources (one row per source).

Apr 23, 2026
Feature

User feedback system. Any authenticated user can submit platform feedback (bug reports, feature requests, questions) via a new modal accessible from the sidebar on web and from the iOS app. Submissions are stored in the database with submitter info and status tracking. Admins get a new Feedback tab with a full list of all submissions, the ability to update status (Open / In Progress / Resolved), add internal notes, and reply to users directly by email. Replying automatically marks the item Resolved. Support page updated with JWT sign-in instructions, expanded FAQs, and App Store link.

Apr 23, 2026
Feature

Public marketing home page at analystintelligence.ai. Elegant dark hero design, AI + human intelligence partnership framing, feature highlights, and "by invitation, free" access messaging. Updated About page with Tom Cipolla's professional biography, career timeline, expertise areas, LinkedIn and contact links. No tech-stack disclosure on public pages.

Apr 23, 2026
Feature

Full mobile phone responsive layout. On small screens the sidebar hides and a bottom tab bar appears with Search, Feed, Digest, Vendors, and Admin. A compact top header shows the current section. Content padding, the Admin pipeline grid, and filter bars all reflow cleanly at phone width. Tablet and desktop layouts are unchanged.

Apr 23, 2026
Bug Fix

Fixed iOS (and web) showing no digest for today's date. Digests were being stored under yesterday's date instead of the generation date, so requesting today always returned 404. The digest job now files entries under the date it runs. Added a graceful API fallback so that requesting today before the digest job completes returns the most recent available digest instead of a hard 404.

Apr 22, 2026
Feature

Added "Legal & Privacy" section to the left nav. Includes quick links to the Privacy Policy, Support, and About pages; a Hosting & Infrastructure table; and a Data Processing Agreement stating that user data will never be sold or used outside the application.

Apr 22, 2026
Feature

Pipeline last-ran timestamps now persist to the database and survive server restarts and deployments. Previously, "Last ran" on the Admin page would reset to "—" after every deploy.

Apr 22, 2026
Feature

Each pipeline step on the Admin page now shows its scheduled run time, when it last ran, and when it will run next — all displayed in your local timezone. Last-ran times are now also tracked for jobs that run automatically on the schedule, not just those triggered manually.

Apr 22, 2026
Feature

Added a refresh button to the Changelog page. Since changelog entries are part of the application itself, the button reloads the page so the latest entries are reflected without manually refreshing the browser.

Apr 22, 2026
Feature

Added refresh buttons to the Digest, Vendors, and Markets pages so you can reload data without navigating away or doing a full page reload. Feed already had one; the button style is consistent across all tabs.

Apr 22, 2026
Feature

The executive summary in each newsletter is now shorter and punchier — one sentence per vendor, under 80 words total, focused on the single most important headline. On quiet days with no notable updates, the summary now says so explicitly rather than being omitted from the email entirely.

Apr 22, 2026
Feature

Added a Re-embed All button in Admin → Semantic Search. Use this after an embedding model upgrade to clear and regenerate all stored vectors. The existing button is now labelled Backfill New and continues to handle routine catch-up of items missing embeddings.

Apr 22, 2026
Bug Fix

Deleting a vendor now permanently removes it and all associated data (sources, raw items, processed items, digest entries). Previously, deleted vendors would reappear after a page reload because the system was only marking them inactive rather than removing them.

Apr 22, 2026
Bug Fix

Fixed a deployment failure on Railway that prevented the rate-limiting feature from loading, causing the application to crash on startup. The build process now guarantees all dependencies are installed even when the build cache is stale.

Apr 22, 2026
Bug Fix

Migrated semantic search from OpenAI's text-embedding-3-small (deprecated October 2026) to text-embedding-3-large. Search quality improves with the upgrade. After this deployment, run Admin → Backfill Embeddings once to regenerate stored vectors — existing search results will be degraded until the backfill completes.

Apr 22, 2026
Bug Fix Feature

Vendor cards now show the correct source count immediately when you add or remove a feed source — no page reload needed. You can now also change which market a vendor belongs to directly from the Edit Vendor screen. A new Changelog tab was added to the bottom of the navigation panel so releases are easy to review.

Apr 22, 2026
Security

Session tokens now expire after 7 days instead of 30, reducing the window of exposure if a token is ever stolen. Password requirements were strengthened — passwords must now be at least 12 characters and include uppercase, lowercase, a number, and a special character. Feed source and vendor website URLs are now validated to block invalid schemes. The user role shown in the sidebar is now verified directly with the server on every page load rather than being read from browser storage, preventing anyone from faking admin access in the interface.

Apr 22, 2026
Security

Login and password reset endpoints now enforce automatic lockouts after repeated failed attempts, preventing brute-force attacks. After signing in on the web dashboard, your session token is now stored in a secure browser cookie that JavaScript cannot read — eliminating a class of attacks where malicious content could steal your login. Admin-only features are now protected by a single centralised check rather than scattered guards, making it easier to maintain consistently. Signing out now immediately invalidates the session on the server.

Apr 22, 2026
Bug Fix

Fixed a crash that prevented the Digest view from loading. Navigating to a specific date's digest would fail with an error; it now loads correctly.

Apr 22, 2026
Security

Completed a full security review of the platform. Hardened the application against common web attacks: locked down which websites can communicate with the API, enforced HTTPS-only connections, strengthened how login tokens are validated, masked internal error details from being visible in the browser, and ensured all API key checks are resistant to timing-based guessing attacks. All authentication events (successful and failed) now record the source IP address for audit purposes.

Apr 22, 2026
Feature

Added a User Management section for administrators. You can now see when each user last logged in, whether they have the iOS app installed, and the date they registered their device. Added the ability to send a push notification directly to a specific user's device, as well as a broadcast tool to send a custom notification to all users or a selected subset.

Apr 22, 2026
Feature

New users can now activate their account directly from the sign-in screen using the invite code sent to them by email. Previously this step was only accessible from the iOS app. The invite email now includes a direct link to the platform for easier onboarding.

Apr 2026
Feature Bug Fix

The Top Story relevance threshold is now configurable from the Admin panel without needing a code change. Digest email recipients are now drawn from the registered user list rather than a hardcoded email address. Improved the user registration flow with a confirmation message on success. Fixed a visual issue with date inputs in dark mode. Added a documentation tab for administrators covering the full platform architecture.

Apr 2026
Feature

Initial web dashboard and iOS backend launch. Includes feed monitoring across multiple markets and vendors, daily digest email delivery, the search feature with AI-generated analyst briefs, user authentication with invite-based onboarding, and iOS push notifications.

Mar 2026
Feature

Initial platform build. Core pipeline established: vendor source monitoring, RSS and web scraping, AI-based relevance scoring, and digest compilation. Deployed to Railway.

User Feedback

Review, respond to, and track feedback submitted by all users.

Admin Notes

Reply to Feedback

Sending email to

After sending, the feedback will automatically be marked as Resolved.

Legal & Privacy

Policies, hosting details, and your data rights.

Hosting & Infrastructure

All application data and processing takes place on the following platforms. No data leaves this infrastructure except as described in the Privacy Policy.

Application
Railway
US-based cloud platform. Backend API, background jobs, and static assets hosted on Railway's managed infrastructure. Privacy policy ↗
Database
PostgreSQL on Railway
All application data — vendors, items, digests, users, embeddings — stored in a private PostgreSQL instance on Railway's US infrastructure. Not publicly accessible.
AI Processing
Anthropic Claude (US)
Item classification, summarisation, and search responses processed by Claude Haiku and Sonnet via Anthropic's API. Content is not used to train Anthropic's models under the API terms. Privacy policy ↗
Search Vectors
OpenAI Embeddings (US)
Item text is sent to OpenAI's Embeddings API to generate semantic search vectors. Vectors are stored in the Railway database. Privacy policy ↗
Email
Resend
Daily digest emails delivered via Resend's transactional email API. Recipient addresses are transmitted to Resend solely for delivery. Privacy policy ↗
Push Alerts
Apple Push Notification service
iOS push notifications delivered through Apple's APNs infrastructure. Only item counts and market names are transmitted in notification payloads. Privacy policy ↗
Data Processing Agreement
Effective: April 2026
1. Scope

This Data Processing Agreement ("DPA") describes how Analyst Intelligence ("the service," "we") processes data provided by or generated on behalf of authorized users ("you," "the user"). It applies to all data submitted to, stored in, or processed by the service.

2. No sale of data

We will not sell, rent, license, or otherwise transfer your data or any data generated through your use of the service to any third party for commercial purposes. Your data is not an asset that changes hands in any transaction involving the service.

3. Use limited to service operation

Data collected through the service — including vendor intelligence content, user accounts, feedback signals, device tokens, and email addresses — is used exclusively to operate and improve the service for you. It is not used for advertising, cross-service profiling, or any purpose outside the functionality described in the application.

4. Sub-processors

The service uses the sub-processors listed in the Hosting & Infrastructure section above to deliver its functionality. Data is shared with these services only to the extent necessary for the specific function they perform (e.g., AI analysis, email delivery). All sub-processors are required under their own terms not to use your data for purposes beyond the service call.

5. Security

All data in transit is encrypted via TLS. Data at rest is stored in a private, non-publicly-accessible PostgreSQL database. Access requires authentication credentials that are never stored in plain text.

6. Data deletion

Users may request deletion of their account and associated data at any time by contacting the administrator. Vendor intelligence content (items, digests) is retained to support the historical search and digest features; individual user data (account, feedback, device tokens) is deleted promptly upon request.

7. Contact

Questions about this agreement or data practices can be directed to [email protected].