Worker Endpoints
There is one Worker —
fcr-dashboard-api(a monolith). It exposes 187 routes (2026-07-02), all registered inworker/src/handlers/**viaregister(path, fn)and dispatched byworker/src/router.js. Every route is…workers.dev/<path>and (except the public ones) requires thex-api-keyheader.
GET /healthis the authoritative, always-current route list. The groups below are a curated guide to the main routes by domain — comprehensive, but not a guaranteed 1:1 mirror of every route the day you read it (new routes land faster than this page). Verified 2026-07-02.
Naming: dashboard-* is the current convention; copysheet-* and a few bare
names are older routes kept for compatibility. Composite endpoints fan out to
several others internally.
Account, CRM & enrichment
Section titled “Account, CRM & enrichment”| Route | Purpose |
|---|---|
dashboard-check-account | CRM + active lines + tickets for a subscriber (the most-called tool) |
dashboard-check-enrichment | Composite: CRM + GBP + keywords + ads + GSC + Ahrefs |
dashboard-check-keywords | Keyword intelligence + gaps |
dashboard-check-tickets | Flexible ticket search |
dashboard-hubspot / -hubspot-deal-live / -hubspot-deals-search | HubSpot deal lookups (live API; BQ is open-only) |
dashboard-hubspot-deal-context | Prior emails/notes/calls for a deal |
dashboard-hubspot-deal-fillrate | Per-deal property fill-rate (data-completeness scoring) |
dashboard-hubspot-properties / -hubspot-engagements-sync | HubSpot property metadata / engagement ingest |
dashboard-resolve-deal-competitor | For a deal naming a free-text competitor, geo-resolve it to a real Places listing before a DF audit (never writes the deal) |
dashboard-active-orders | Current active recurring order lines (real MRR: line_tag IN ('Sub','Sold With'), ri_period > 0) — Quick’s quick.fcr.clients primitive |
dashboard-save-note-to-deal | One-tap “Save to notes” from the HubSpot card — posts a NOTE on the deal attributed to the rep |
dashboard-suspensions, dashboard-reconciliation, dashboard-data-freshness | billing/ops state + freshness checks |
dashboard-roam-users / -roam-users-sync / -roam-user-list-verify | person ↔ Roam ↔ HubSpot identity (sync = daily 09:00 cron from api.ro.am user.info; verify = read-only diff) |
dashboard-usage-log, dashboard-track-engagement | telemetry |
Deal brief (precompute pipeline)
Section titled “Deal brief (precompute pipeline)”| Route | Purpose |
|---|---|
dashboard-compose-deal-brief | Fan-out composer → writes KV deal-brief:<id> + BQ audit |
dashboard-get-deal-brief | Hot KV read (lazy-compose + self-heal on miss) |
dashboard-brief-refresh-cron | Chunked staleness sweep → enqueues to BRIEF_QUEUE |
dashboard-crawl-website | Fetch + extract a site’s services/CTA/CMS (shared by advisor + brief) |
HubSpot card chat
Section titled “HubSpot card chat”| Route | Purpose |
|---|---|
dashboard-hubspot-chat-start / -status / -complete | async job: kick off / poll / finish a card turn. -start enqueues onto fcr-hubspot-chat-queue (HUBSPOT_CHAT_TRANSPORT="queue" since 2026-06-10; "n8n" reverts to the legacy n8n webhook hop, and an enqueue failure auto-falls-back to it). -complete writes the result to KV and the per-session ProgressDO; -status reads completion from the DO so the poll never waits out KV’s ~60s edge cache |
dashboard-hubspot-chat-prewarm | card-mount warm-up: seeds session-facts + brief, and (when the card passes hubspotUserEmail) resolves the rep’s identity + personal/team template libraries into advisor-identity:<email> (10-min TTL) so the first send skips three BigQuery lookups |
dashboard-hubspot-chat-history / dashboard-chat-history | restore visible chat |
The card’s deal also rides into the advisor as
_anchorDealId— the worker injects the precomputed deal brief into the system context before the first model call, so deal-anchored questions answer in one model pass with zero tool calls (previously a mandatedget_deal_brieftool iteration, ~8–15s/turn).
AI advisor & vector indexes
Section titled “AI advisor & vector indexes”| Route | Purpose |
|---|---|
dashboard-ai-advisor | The advisor (Claude + 72 tools). Roam + card both call this. |
dashboard-vector-search / -vector-reindex | fcr-site-portfolio (similar sites) |
dashboard-deals-vector-search / -deals-vector-reindex (+-cron) | fcr-deal-history (similar deals); -cron is the daily incremental re-embed |
dashboard-company-knowledge-search / -reindex, dashboard-case-studies-reindex | fcr-company-knowledge |
dashboard-docs-search / -docs-reindex | fcr-internal-docs — RAG over the published docs site (“Ask the docs”); reindex after every docs deploy |
dashboard-deal-patterns | Mine recurring win/loss themes across a deal cohort |
dashboard-deals-cohort-raw-backfill | One-off backfill of the frozen back-catalogue cohorts’ raw_payload JSON |
Marketing content curation (governed write surface)
Section titled “Marketing content curation (governed write surface)”| Route | Purpose |
|---|---|
dashboard-marketing-knowledge | Index/de-index free-form company-knowledge docs into the shared fcr-company-knowledge index |
dashboard-marketing-products | The FCR product catalogue (source of truth) — re-renders the advisor price block + re-indexes each product |
dashboard-marketing-outreach / -outreach-search | Marketing-approved outreach templates in the standalone fcr-outreach-templates index |
These three are the sanctioned content-admin carve-out: confirm-first,
--dry-run, soft-delete (active=FALSE), audit tofcr_operations.marketing_kb_audit. All other marketing data writes stay n8n-only (seemarketing-skills.md).
Ads & Merchant Centre
Section titled “Ads & Merchant Centre”copysheet-ads-stats, dashboard-ads-spend, dashboard-ads-spend-all,
dashboard-ads-quality, dashboard-ads-no-conversions, ads-performance-report,
ads-aimax-audit (AI Max migration audit), dashboard-ads-mtd (month-to-date per
account — Quick’s quick.fcr.ads primitive), dashboard-ads-account-detail
(one account’s full ads detail, fans out in-process to check-account + ads-stats),
dashboard-gmc-stats.
These read
2_Ads_Data_view, which buckets Performance Max by the campaign’sadvertising_channel_type(Google droppedad_network_type=MIXEDfor PMax 2026-05-19 — never bucket by campaign name). Ads spend is retail (what the client pays FCR) — never call it media spend.
GBP & reviews
Section titled “GBP & reviews”copysheet-dashboard-gbp (cached GBP from BQ), dashboard-gbp-live (live
SerpAPI+Pleper), dashboard-gbp-services, dashboard-reviews,
dashboard-competitor-enrich.
Analytics (GA4 / GSC)
Section titled “Analytics (GA4 / GSC)”copysheet-ga4-stats, copysheet-ga4-traffic-sources, copysheet-gsc-stats.
Keywords & category intelligence
Section titled “Keywords & category intelligence”dashboard-keyword-intelligence, dashboard-keyword-gap,
dashboard-keyword-planner, dashboard-category-keywords,
dashboard-category-gaps, dashboard-prospect-categories,
dashboard-saymore-keyword-matrix.
Prospecting, discovery & InSites
Section titled “Prospecting, discovery & InSites”| Route | Purpose |
|---|---|
dashboard-prospect-intel | All-in-one category/prospect intelligence (similar clients, keywords, area) |
dashboard-prospect-search | Google Maps search (place_id, lat/lng) via SerpAPI |
dashboard-prospect-audit / -listings / -categories | prospect data lookups |
dashboard-prospect-enrich / -crawl-enrich / -pleper-refresh / -engagement / -engagements-refresh | enrichment (GBP + website crawl) + steady-state refresh drains |
dashboard-prospect-enable-enrich | Flip enrich_enabled on a prospect cohort (gates the crons; dry-run → cost → commit) |
dashboard-prospect-seo-enrich / -seo-keywords / -serp-competitors | Fill dim_seo (Ahrefs DR + organic traffic) for live prospect domains, the thin-but-ranking keyword deep pull, and live IE SERP competitor-DR harvest into dim_seo_serp_competitors |
dashboard-prospect-opportunity-search / -vector-reindex | Semantic retrieval over the fcr-prospect-opportunities index (+ its offline rebuild) |
dashboard-prospect-review-mine | Mine services/hours/themes from GBP review TEXT (unlisted-service gap signals) |
dashboard-seo-pitch-targets | Relevance-gated, commercial-weighted prospect SEO pitch list |
dashboard-discovery-suggest / -insights / -df-compare / -edit | Discovery (Alpha) map flow |
dashboard-snap-upload / -roam | Prospect Snap Chrome extension — store a captured advert PNG to R2, run the advisor over it, DM the on-file verdict to the rep in Ro.am |
dashboard-insites-bq-lookup / -poll / -report-summary / -settings / -share / -suggest | InSites audits (DF / LRC) |
Post Studio (GBP/Yext post composer + publish)
Section titled “Post Studio (GBP/Yext post composer + publish)”| Route | Purpose |
|---|---|
post-studio-draft | Draft a GBP/Yext post — crawls the grounding URL + structured business/product fields |
post-studio-post-suggest / -image-suggest | Suggest post copy / image options |
post-studio-image-generate | Generate a post image (Creator/Modal pipeline) |
post-studio-search | Search a subscriber’s listings/entities for the composer |
post-studio-publish / dashboard-yext-posts | Publish to Yext Posts (real GBP / firstparty publish) |
post-studio-handoff-create / -poll / -complete | Chat→Studio image handoff — persist dropped images to R2 + JWT, poll, finalise |
dashboard-post-studio-brand / -gbp-photos / -products | Per-subscriber brand config, GBP owner photos, Merchant Centre product feed |
Planning & Segment Studio (cohort engine)
Section titled “Planning & Segment Studio (cohort engine)”| Route | Purpose |
|---|---|
dashboard-segment-build | Build a cohort from segment_spine — the Marketing & Planning Studio engine (reads the clustered rollup, never raw PROSPECT_LISTINGS) |
dashboard-segment-crossmatch | Cross-index correlation across cohorts |
dashboard-segment-save | Persist a named cohort DEFINITION |
dashboard-planning-advise | The Planning Studio’s reasoning / advice layer |
Next-Best-Action (NBA)
Section titled “Next-Best-Action (NBA)”| Route | Purpose |
|---|---|
dashboard-nba-run | New-deal sweep — playbook decides the action, enqueues an autonomous advisor draft + HubSpot review task + Roam DM (cron-driven; gated by NBA_ENABLED) |
dashboard-nba-stall-run | Idle-deal stall sweep — re-runs NBA on open pilot deals with no movement in NBA_STALL_DAYS |
dashboard-nba-draft-completion-run | DF-completion sweep — auto-completes a pending NBA draft from a finished Digital Footprint report (draft_from_report, no re-scan) |
dashboard-nba-precompute | Precompute one deal’s glance + next-action draft into KV deal-nba:<id> (LIVE for pilot owners via NBA_PRECOMPUTE) |
dashboard-nba-playbooks | Governed editor API for the sales-owned playbooks (BQ source of truth → KV prompt block, audit rows, JWT-verified editors) |
Full engine + playbooks write-up:
next-best-action.md.
SERP, grid maps & reports
Section titled “SERP, grid maps & reports”dashboard-serp-grid, dashboard-serp-local (+-batch),
dashboard-serp-screenshot (+-batch), dashboard-grid-map-build (+ the
/r/:id shareable viewer), dashboard-area-map, dashboard-map-advisor,
dashboard-lrc-methodology, dashboard-proposal-localities / -publish /
-retest, dashboard-report-get / -list / -save / -resolve / -annotate,
dashboard-meeting-brief-render.
Area, demographics & reach
Section titled “Area, demographics & reach”dashboard-circle-demographics, dashboard-bbox-demographics,
dashboard-meta-reach (+-batch).
Ahrefs / SEO
Section titled “Ahrefs / SEO”dashboard-ahrefs-seo, dashboard-ahrefs-by-url.
Portfolio, revenue & reporting
Section titled “Portfolio, revenue & reporting”dashboard-am-portfolio, dashboard-am-bridge, dashboard-am-attributes,
dashboard-am-email-templates, dashboard-am-team-email-templates,
dashboard-solution-portfolio, dashboard-revenue-bridge,
dashboard-sales-rep-bridge, dashboard-built-websites,
dashboard-pipeline-review (monthly product pipeline review — open book by
channel + per-rep split, published to FCR Quick).
Call tracking (iovox)
Section titled “Call tracking (iovox)”dashboard-iovox, dashboard-iovox-all, dashboard-iovox-counts.
Teamwork (projects + tickets)
Section titled “Teamwork (projects + tickets)”dashboard-tickets, dashboard-twd-deep-dive, dashboard-teamwork-desk-ticket
(+-tickets), dashboard-teamwork-project (+-projects).
SitePro / Yext / build pipeline
Section titled “SitePro / Yext / build pipeline”dashboard-sitepro, dashboard-yext-listings, dashboard-yext-sync,
dashboard-build-pipeline, dashboard-build-detail.
Voice (speech-to-text)
Section titled “Voice (speech-to-text)”dashboard-stt, dashboard-stt-fetch (Whisper-backed dictation for the card).
Pre-warm & scheduled (also HTTP-exposed for manual runs)
Section titled “Pre-warm & scheduled (also HTTP-exposed for manual runs)”dashboard-prewarm-am-portfolios, dashboard-prewarm-open-deal-subscribers,
dashboard-brief-refresh-cron, dashboard-deals-vector-reindex-cron,
dashboard-advisor-usage-report, dashboard-advisor-usage-view (per-user
advisor-usage dashboard read), dashboard-api-usage-report,
dashboard-scheduled-jobs (on-demand health check of all crons + table
freshness — see architecture-overview),
dashboard-crawl-slow-hosts (recent slow-host crawl metrics for tuning the
crawler’s per-host deadline).
The Mon 08:00 UTC cron DMs two weekly reports to Ro.am: the advisor usage
report (from advisor_usage_log) and the external-API usage report (Ahrefs +
HubSpot vendor meters + the Teamwork worker counter — see
external-apis.md). Both accept
?dry=true to compute without sending; dashboard-api-usage-report is in
NO_CACHE_ROUTES so it always runs live.
Admin / infrastructure
Section titled “Admin / infrastructure”| Route | Purpose |
|---|---|
dashboard-bq-execute | Ad-hoc read-only BigQuery |
dashboard-bq-admin | DDL / writes — requires x-admin-key on top of x-api-key |
dashboard-bq-create-table | table creation helper |
dashboard-sheet-read | Read cell values from a shared Google Sheet (via the BQ service account) |
/health | route list + status (no auth) |
/voice-stt | public HTML iframe for dictation |
How a route is added
Section titled “How a route is added”- Create
worker/src/handlers/<name>.jswithregister("dashboard-<name>", async (params, env, ctx, request) => {…}). import "./handlers/<name>.js";inworker/src/index.js.- Deploy via
scripts/deploy-worker.sh(seecommit-and-deploy.md). The route is then live at…workers.dev/dashboard-<name>and appears in/health.