Skip to content

Worker Endpoints

There is one Worker — fcr-dashboard-api (a monolith). It exposes 187 routes (2026-07-02), all registered in worker/src/handlers/** via register(path, fn) and dispatched by worker/src/router.js. Every route is …workers.dev/<path> and (except the public ones) requires the x-api-key header.

GET /health is 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.


RoutePurpose
dashboard-check-accountCRM + active lines + tickets for a subscriber (the most-called tool)
dashboard-check-enrichmentComposite: CRM + GBP + keywords + ads + GSC + Ahrefs
dashboard-check-keywordsKeyword intelligence + gaps
dashboard-check-ticketsFlexible ticket search
dashboard-hubspot / -hubspot-deal-live / -hubspot-deals-searchHubSpot deal lookups (live API; BQ is open-only)
dashboard-hubspot-deal-contextPrior emails/notes/calls for a deal
dashboard-hubspot-deal-fillratePer-deal property fill-rate (data-completeness scoring)
dashboard-hubspot-properties / -hubspot-engagements-syncHubSpot property metadata / engagement ingest
dashboard-resolve-deal-competitorFor 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-ordersCurrent 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-dealOne-tap “Save to notes” from the HubSpot card — posts a NOTE on the deal attributed to the rep
dashboard-suspensions, dashboard-reconciliation, dashboard-data-freshnessbilling/ops state + freshness checks
dashboard-roam-users / -roam-users-sync / -roam-user-list-verifyperson ↔ Roam ↔ HubSpot identity (sync = daily 09:00 cron from api.ro.am user.info; verify = read-only diff)
dashboard-usage-log, dashboard-track-engagementtelemetry
RoutePurpose
dashboard-compose-deal-briefFan-out composer → writes KV deal-brief:<id> + BQ audit
dashboard-get-deal-briefHot KV read (lazy-compose + self-heal on miss)
dashboard-brief-refresh-cronChunked staleness sweep → enqueues to BRIEF_QUEUE
dashboard-crawl-websiteFetch + extract a site’s services/CTA/CMS (shared by advisor + brief)
RoutePurpose
dashboard-hubspot-chat-start / -status / -completeasync 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-prewarmcard-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-historyrestore 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 mandated get_deal_brief tool iteration, ~8–15s/turn).

RoutePurpose
dashboard-ai-advisorThe advisor (Claude + 72 tools). Roam + card both call this.
dashboard-vector-search / -vector-reindexfcr-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-reindexfcr-company-knowledge
dashboard-docs-search / -docs-reindexfcr-internal-docs — RAG over the published docs site (“Ask the docs”); reindex after every docs deploy
dashboard-deal-patternsMine recurring win/loss themes across a deal cohort
dashboard-deals-cohort-raw-backfillOne-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)”
RoutePurpose
dashboard-marketing-knowledgeIndex/de-index free-form company-knowledge docs into the shared fcr-company-knowledge index
dashboard-marketing-productsThe FCR product catalogue (source of truth) — re-renders the advisor price block + re-indexes each product
dashboard-marketing-outreach / -outreach-searchMarketing-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 to fcr_operations.marketing_kb_audit. All other marketing data writes stay n8n-only (see marketing-skills.md).

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’s advertising_channel_type (Google dropped ad_network_type=MIXED for PMax 2026-05-19 — never bucket by campaign name). Ads spend is retail (what the client pays FCR) — never call it media spend.

copysheet-dashboard-gbp (cached GBP from BQ), dashboard-gbp-live (live SerpAPI+Pleper), dashboard-gbp-services, dashboard-reviews, dashboard-competitor-enrich.

copysheet-ga4-stats, copysheet-ga4-traffic-sources, copysheet-gsc-stats.

dashboard-keyword-intelligence, dashboard-keyword-gap, dashboard-keyword-planner, dashboard-category-keywords, dashboard-category-gaps, dashboard-prospect-categories, dashboard-saymore-keyword-matrix.

RoutePurpose
dashboard-prospect-intelAll-in-one category/prospect intelligence (similar clients, keywords, area)
dashboard-prospect-searchGoogle Maps search (place_id, lat/lng) via SerpAPI
dashboard-prospect-audit / -listings / -categoriesprospect data lookups
dashboard-prospect-enrich / -crawl-enrich / -pleper-refresh / -engagement / -engagements-refreshenrichment (GBP + website crawl) + steady-state refresh drains
dashboard-prospect-enable-enrichFlip enrich_enabled on a prospect cohort (gates the crons; dry-run → cost → commit)
dashboard-prospect-seo-enrich / -seo-keywords / -serp-competitorsFill 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-reindexSemantic retrieval over the fcr-prospect-opportunities index (+ its offline rebuild)
dashboard-prospect-review-mineMine services/hours/themes from GBP review TEXT (unlisted-service gap signals)
dashboard-seo-pitch-targetsRelevance-gated, commercial-weighted prospect SEO pitch list
dashboard-discovery-suggest / -insights / -df-compare / -editDiscovery (Alpha) map flow
dashboard-snap-upload / -roamProspect 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 / -suggestInSites audits (DF / LRC)

Post Studio (GBP/Yext post composer + publish)

Section titled “Post Studio (GBP/Yext post composer + publish)”
RoutePurpose
post-studio-draftDraft a GBP/Yext post — crawls the grounding URL + structured business/product fields
post-studio-post-suggest / -image-suggestSuggest post copy / image options
post-studio-image-generateGenerate a post image (Creator/Modal pipeline)
post-studio-searchSearch a subscriber’s listings/entities for the composer
post-studio-publish / dashboard-yext-postsPublish to Yext Posts (real GBP / firstparty publish)
post-studio-handoff-create / -poll / -completeChat→Studio image handoff — persist dropped images to R2 + JWT, poll, finalise
dashboard-post-studio-brand / -gbp-photos / -productsPer-subscriber brand config, GBP owner photos, Merchant Centre product feed
RoutePurpose
dashboard-segment-buildBuild a cohort from segment_spine — the Marketing & Planning Studio engine (reads the clustered rollup, never raw PROSPECT_LISTINGS)
dashboard-segment-crossmatchCross-index correlation across cohorts
dashboard-segment-savePersist a named cohort DEFINITION
dashboard-planning-adviseThe Planning Studio’s reasoning / advice layer
RoutePurpose
dashboard-nba-runNew-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-runIdle-deal stall sweep — re-runs NBA on open pilot deals with no movement in NBA_STALL_DAYS
dashboard-nba-draft-completion-runDF-completion sweep — auto-completes a pending NBA draft from a finished Digital Footprint report (draft_from_report, no re-scan)
dashboard-nba-precomputePrecompute one deal’s glance + next-action draft into KV deal-nba:<id> (LIVE for pilot owners via NBA_PRECOMPUTE)
dashboard-nba-playbooksGoverned 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.

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.

dashboard-circle-demographics, dashboard-bbox-demographics, dashboard-meta-reach (+-batch).

dashboard-ahrefs-seo, dashboard-ahrefs-by-url.

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).

dashboard-iovox, dashboard-iovox-all, dashboard-iovox-counts.

dashboard-tickets, dashboard-twd-deep-dive, dashboard-teamwork-desk-ticket (+-tickets), dashboard-teamwork-project (+-projects).

dashboard-sitepro, dashboard-yext-listings, dashboard-yext-sync, dashboard-build-pipeline, dashboard-build-detail.

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.

RoutePurpose
dashboard-bq-executeAd-hoc read-only BigQuery
dashboard-bq-adminDDL / writes — requires x-admin-key on top of x-api-key
dashboard-bq-create-tabletable creation helper
dashboard-sheet-readRead cell values from a shared Google Sheet (via the BQ service account)
/healthroute list + status (no auth)
/voice-sttpublic HTML iframe for dictation

  1. Create worker/src/handlers/<name>.js with register("dashboard-<name>", async (params, env, ctx, request) => {…}).
  2. import "./handlers/<name>.js"; in worker/src/index.js.
  3. Deploy via scripts/deploy-worker.sh (see commit-and-deploy.md). The route is then live at …workers.dev/dashboard-<name> and appears in /health.
Ask the docsRAG over this site
Ask anything about the FCR Dashboard platform — architecture, BigQuery, the worker routes, billing rules, the LRC stack, scoring… Answers are grounded in this documentation, with source links.
How does the deal-brief refresh work? Which routes are Worker vs n8n? How is account health scored?