API Reference
Base URL: https://firmhound.com (or http://localhost:3877 for development)
Health & Status
GET
/health
Basic health check. Returns 200 if the server is running.
{"status": "ok", "service": "firmhound-portfolio", "ts": 1776526873502}
GET
/status
Operational overview: product count, active sources, alert count, last scrape, uptime.
{"status": "operational", "products": 14, "activeSources": 9, "totalAlerts": 226, ...}
Products
GET
/products
List all 14 products with public fields (name, domain, tagline, pricing, accent color).
GET
/products/:id
Get a single product by ID.
Alert Preview
GET
/preview/:productId
5 most recent alert titles and summaries (200 chars) for a product. No auth required. Used by product landing pages.
Waitlist
POST
/waitlist
Join the waitlist for a coming-soon product.
| Body | Type | Description |
|---|---|---|
| string | Valid email address | |
| productId | string | Product ID (e.g., "senatortrades") |
Authentication
POST
/auth/signup
Create an account. Returns JWT token. Rate limited: 5 signups/hour per IP.
| Body | Type | Description |
|---|---|---|
| string | Valid email address | |
| password | string | 8+ characters |
{"token": "eyJ...", "user": {"id": "...", "email": "user@example.com"}}
POST
/auth/login
Login. Rate limited: 10 attempts/minute per IP.
GET
/auth/me
JWT
Get current user profile, subscriptions, and preferences.
Preferences
GET
/auth/preferences
JWT
Get notification preferences (digest_frequency, timezone).
PUT
/auth/preferences
JWT
Update notification preferences.
| Body | Type | Options |
|---|---|---|
| digest_frequency | string | "immediate" | "daily" | "weekly" |
| timezone | string | IANA timezone (e.g., "America/New_York") |
Alerts
GET
/alerts
JWT
Get alerts for products the user subscribes to. Returns enriched content.
| Query | Type | Description |
|---|---|---|
| product_id | string | Filter by product (optional) |
| limit | number | Max results, 1-100 (default 50) |
Billing
POST
/billing/checkout
JWT
Create a Stripe checkout session for a product subscription.
| Body | Type | Description |
|---|---|---|
| productId | string | Product ID to subscribe to |
{"url": "https://checkout.stripe.com/...", "sessionId": "cs_..."}
POST
/billing/cancel
JWT
Cancel an active subscription.
GET
/billing/subscriptions
JWT
List all subscriptions for the authenticated user.
Scraping (Internal)
POST
/scrape/:productId
Internal Key
Trigger a single product scraper. Header:
X-Internal-Key
POST
/scrape/all
Internal Key
Run all scrapers in parallel batches of 4. Returns aggregate results.
Digest (Internal)
POST
/digest
Internal Key
Send email digests of undelivered alerts to all subscribers.
Admin (Internal)
GET
/admin/stats
Internal Key
Dashboard statistics: alert counts, user counts, runs, per-product breakdown.
GET
/scrape-runs
Internal Key
Recent scrape run history (last 50).