An n8n flow that catches account-level intent spikes from Common Room, 6sense (via Salesforce CRM sync), and Bombora (via Salesforce CRM sync), deduplicates within a day-level window, assigns each spike to the existing Salesforce account owner or a territory-based SDR pool, asks Claude to draft a first-touch message anchored to the specific topics the account is researching, and delivers the full context — draft included — as a Slack notification and a Salesforce Task. The bundle at apps/web/public/artifacts/intent-spike-handler-n8n/ ships the complete n8n export plus a _README.md covering import, environment variables, credential setup, Salesforce custom fields, and per-branch verification.
When to use this
Use it when your intent data is flowing into Salesforce (via 6sense or Bombora managed packages) or Common Room, but rep follow-up on spikes is inconsistent — some accounts get actioned within the hour, others sit untouched for days because the signal arrived in a CRM view nobody checks. The symptom is that your intent vendor’s reporting shows high-spike accounts that never received a first touch within the same week.
It’s also the right pattern when you have more than one SDR covering territory and you want spikes routed to the right rep automatically rather than landing in a shared inbox where ownership is ambiguous. The flow’s assignment logic checks the Salesforce Account owner first; if no Account exists, it routes to AMER, EMEA, or ROW SDR pool based on the account’s billing country. That rule is in a Code node, not a config file, so the ops team can audit and change it without opening a JIRA ticket.
The draft-not-send design is intentional. Intent data tells you an account is researching a topic, not that a specific person is ready for a pitch. The Claude draft is a starting point for the SDR to edit before sending — it references the specific topics the account is researching, which cuts the SDR’s research time from 10–15 minutes to under 2 minutes, but the rep’s judgment on timing and tone stays in the loop.
When NOT to use this
Skip it if your intent platforms are not syncing data to Salesforce. The polling path depends on Salesforce Account fields written by the 6sense or Bombora managed packages. Without those fields, the polling path returns zero rows. The real-time path (Common Room outgoing webhooks) works independently, but if you’re running neither integration, there’s nothing to ingest.
Also skip it if your SDR team has fewer than 3 reps and already reviews intent signals in the platform UI daily. At that size and discipline, the notification layer adds infrastructure cost without materially changing response time. The automation pays off when the team is large enough that no one person can monitor every account’s signal every day.
Do not use this as the sole gating mechanism for high-value accounts. The flow handles the notification and Task creation; it does not replace the weekly account review where the AE and SDR decide which spikes to prioritize. A high-severity Slack notification does not mean the account is ready to buy — it means someone at that company is researching relevant topics. The rep decides what to do with that information.
Finally, be aware that this flow does not handle the case where the same person has been previously contacted. It looks up the Salesforce Account but does not check whether a contact at the account is already in an active sequence. Before the SDR sends the Claude draft, they should verify in their sequencing tool that the contact isn’t already enrolled.
Setup
Import the bundle. Drop apps/web/public/artifacts/intent-spike-handler-n8n/intent-spike-handler-n8n.json into n8n via Workflows → Import from File. Two entry points: a webhook for the real-time Common Room path, and a Schedule Trigger polling Salesforce every 4 hours for the 6sense/Bombora CRM-sync path.
Set environment variables. The flow uses 10 environment variables (instance URLs, SDR pool emails and Slack handles). Set them in n8n Cloud under Settings → Environment Variables or in your self-hosted .env. Full list and where to find each value is in _README.md.
Wire credentials. Four credentials are required:
PLACEHOLDER_ANTHROPIC_CRED_ID — HTTP Header Auth with x-api-key set to your Anthropic key
PLACEHOLDER_SLACK_CRED_ID — HTTP Header Auth with Authorization: Bearer xoxb-…
PLACEHOLDER_SALESFORCE_CRED_ID — HTTP Header Auth with Authorization: Bearer <sfdc_token> (or a Connected App OAuth credential for production)
No direct 6sense or Bombora credential is needed in n8n — data arrives via Salesforce Account fields written by those vendors’ managed packages
Create Salesforce custom fields. Three fields on the Task object: Intent_Spike_Source__c (Text 50), Intent_Score__c (Number 18,0), Intent_Buying_Stage__c (Text 50). The 6sense and Bombora Account fields (sixsense_Intent_Score__c, sixsense_Buying_Stage__c, etc.) are installed by the vendor packages — verify the API names match what’s in your org.
Wire Common Room (real-time path). In Common Room, add an outgoing webhook pointing to https://<your-n8n-host>/webhook/intent-spike-handler with payload type Organization. Set a workflow trigger on whatever signal defines a spike for your team (e.g., “new high-intent account activity,” buying stage change to Decision or Purchase).
Verify every path. Walk the five-step verification in _README.md before enabling the workflow. The dedup test (step 2) is the most important — run it before going live to confirm duplicate spikes are silently dropped.
What the flow does
Webhook — Intent Spike Ingest accepts POST requests and immediately returns 202 to the caller. Normalize Intent Payload is a Code node that handles three payload shapes: Common Room’s organization webhook format (detected by type: "organization"), a 6sense CRM-sync shape forwarded by the Polling Cron (detected by _source: "6sense"), and a Bombora CRM-sync shape (detected by _source: "bombora"). The normalization step maps each shape to a single internal record with consistent fields: domain, accountName, intentScore, buyingStage, topTopics, spikeSeverity. Spike severity (low/medium/high) is derived from buying stage first (Decision and Purchase map to high; Consideration to medium; Awareness and Target to low) and from numeric intent score as a fallback (≥70 = high, 40–69 = medium, <40 = low). This derivation is explicit in the Code node so the ops team can read and change the thresholds.
Dedup Gate (Static Data) is a single Code node that handles the whole dedup in one place using n8n’s workflow static data — $getWorkflowStaticData('global'). That object is the only correct way to persist cross-execution state from a Code node: n8n’s public REST API has no static-data resource, so a previous HTTP-based design would have 404’d every call and the gate would silently never fire — flooding reps with exactly the repeat notifications it claims to prevent. The node reads/writes a per-account-per-day key (dedup_acme.com_2026-05-23). If the key already exists, the flow actioned this account today and the node returns an empty array, halting execution silently. If not, it stamps the key before any external call — preventing a race where two concurrent spikes for the same domain both pass — and prunes keys from previous days so the store stays small. The day-level window is the right dedup horizon because intent platforms often re-score accounts every few hours; without a window, the same spike generates 4–6 notifications per day per account. One caveat: n8n persists static data only on production executions (webhook or schedule trigger), not manual test runs, so dedup is verified by hitting the live webhook twice rather than via the Execute Workflow button.
Salesforce — Account Lookup queries Salesforce for an Account where the Website field contains the spike’s domain. It retrieves the Account’s OwnerId, Owner.Name, Owner.Email, and a custom Owner.Slack_Handle__c field. Assignment Logic uses the result: if an Account was found, the existing owner gets the spike, and the node captures the owner’s Salesforce User Id (OwnerId, a 15/18-char Id starting with 005) for use as the Task owner. If no Account was found, the node selects a territory pool using the account’s billing country against three Sets (AMER, EMEA, ROW). Pool emails and Slack handles come from environment variables so no code change is needed to update the routing. The isUrgent flag is set true for high-severity spikes, which affects the Slack notification color (red vs. yellow) and the Salesforce Task due date (+1 day vs. +3 days).
Claude — Draft First Touch posts to the Anthropic API with claude-haiku-4-5, an 8-second timeout, and neverError: true. The system prompt explicitly bans filler phrases (“I noticed,” “reach out,” “touch base,” “circle back”) and instructs Claude to reference the specific research topics — not generic industry pain — because a draft that says “I see you’re evaluating CRM automation and pipeline management tools” is actionable, while one that says “I’d love to connect about your operations challenges” is not. The draft is labeled explicitly as a starting point in both the system prompt and the Slack message so reps don’t misread it as ready-to-send. Parse Draft (with fallback) handles Claude timeouts or malformed JSON by producing a template-based draft tagged draftSource: template-fallback. Both paths produce the same three fields: draftSubject, draftBody, draftTalkingPoint.
Slack — Notify Assignee posts to #intent-spikes with a structured Block Kit message: a header line with severity indicator and @-mention of the assignee’s Slack handle, a firmographics block (industry, headcount, country, buying stage, intent score, top topics), and the Claude draft with explicit “edit before sending” label. Salesforce — Create Task creates a Task linked to the Account (via WhatId) with the full context in the Description field and the three custom intent fields populated. When the account owner was resolved, the Task’s OwnerId is set to that owner’s Salesforce User Id — never an email, which Salesforce rejects with MALFORMED_ID. When the spike routed to an SDR pool (no Account), OwnerId is omitted so the Task defaults to the integration user; WhatId is likewise omitted rather than sent empty, and the intended rep is recorded in the Description and @-mentioned in Slack.
The second entry point — Polling Cron — Every 4h — queries Salesforce for Accounts modified in the last 4 hours where the 6sense buying stage is Decision or Purchase, or the Bombora surge level is high. Build Forward Payloads converts each Account record into the appropriate CRM-sync payload shape, and Forward to Ingest Webhook POSTs each one to the main webhook with batchSize: 3 and batchInterval: 3000ms to avoid hammering the Anthropic and Salesforce APIs during a burst.
Cost reality
Per spike, claude-haiku-4-5 receives roughly 700 input tokens (system prompt + account firmographics + topics) and produces around 150 output tokens for the three-field draft. At Haiku 4.5’s pricing (~$0.80/M input, ~$4/M output), that’s approximately $0.0009 per spike — under $0.001. For a team processing 500 intent spikes per month, the Claude cost is under $0.50/month. The dedup window means high-volume accounts that spike repeatedly intraday are only billed once per day per account.
The Salesforce API calls (one query + one Task create per spike) consume your org’s daily API call limit. Salesforce Enterprise allows 150,000 API calls per 24 hours by default; at 500 spikes/month (~17/day), this flow uses roughly 34 calls/day — well under typical limits. The polling path adds a batch query every 4 hours (6 queries/day) regardless of spike volume.
n8n self-hosted is free; n8n Cloud Starter at $20/month handles 5,000 executions per month, which comfortably covers 500 spikes at roughly 8 nodes per spike (4,000 node executions). Common Room’s outgoing webhook feature is available on their Pro plan (~$1,500/month list, frequently discounted on annual contracts). The Slack bot and the n8n webhook endpoint are free.
Failure modes
6sense / Bombora field names don’t match. The SOQL query in Salesforce — Poll Intent Fields uses specific API names (sixsense_Intent_Score__c, Bombora_Composite_Score__c, etc.). If your vendor installed their managed package under a different namespace or with different field names, the query returns zero rows silently. Guard: after import, run Salesforce — Poll Intent Fields manually and inspect the raw output. If the records come back but the intent fields are null, compare the field API names in the SOQL to what’s actually on your Account object in Salesforce Setup → Object Manager → Account → Fields & Relationships. Update the SOQL and the Build Forward Payloads Code node to match.
Dedup static data persists only on production runs. The Dedup Gate (Static Data) node reads and writes $getWorkflowStaticData('global'), which n8n saves to its database only when the execution is triggered in production (a real webhook POST or the Schedule Trigger) — never on a manual Execute Workflow run. If you test dedup by clicking Execute Workflow twice, the second run will not see the first run’s key and the gate appears broken when it is working as designed. Guard: activate the workflow and POST to the live webhook URL twice to verify the block (the verification in _README.md calls this out). The node prunes keys from previous days on every run, so the store self-cleans and does not grow unbounded; no separate maintenance cron is needed.
Salesforce Bearer token rotation breaks the polling path. The raw Bearer token in SFDC_ACCESS_TOKEN rotates every 2 hours by default on Salesforce orgs without a persistent session policy. When it expires, Salesforce — Poll Intent Fields and Salesforce — Account Lookup return 401 errors silently (because neverError: true). Guard: watch for a pattern of Salesforce nodes returning empty results even when you know intent spikes are occurring. For production, replace the raw Bearer token approach with a Salesforce Connected App using OAuth 2.0 client credentials flow (server-to-server) and configure a token refresh in the n8n credential settings. The _README.md covers this setup.
Claude draft draft cites outdated topics. The topTopics field from Common Room or Bombora is a semi-colon-delimited string from the platform’s last sync window. If the platform hasn’t synced in 12+ hours, the topics may reflect research from two days ago. Guard: the Slack notification includes the receivedAt timestamp and the intent source so the SDR can cross-check the signal age before acting on the draft. If stale topics are a recurring issue, add a freshness check in Normalize Intent Payload that flags records where no sync timestamp is available.
vs alternatives
vs native 6sense Workflows (Orchestrations). 6sense’s own Orchestrations feature (generally available as of Q1 2025) can trigger actions like enrolling contacts in Outreach or Salesloft sequences directly from intent signals. It’s the right tool if your action is enrollment in an existing sequence. It’s not the right tool if you want: (a) a draft message tailored to the specific research topics, (b) a Salesforce Task as the first-touch record rather than a sequence enrollment, or (c) multi-source normalization across both 6sense and Bombora in the same routing path. The n8n flow composes with Orchestrations — use Orchestrations for sequence enrollment on high-confidence accounts and this flow for the notification + Task creation layer.
vs manual SDR triage. The status quo for most teams is a shared Slack channel or CRM view where intent signal summaries land. SDRs check it when they have time. The primary cost is response latency — median time from spike to first touch at the median team is measured in days, not hours, because the SDR queue is deep and intent alerts are not prioritized over scheduled activities. This flow does not guarantee faster response; it guarantees the right rep sees the spike immediately with the context they need to act. Whether they act is still a behavior question, not a tool question.
vs a Clay table that scrapes intent signals. Clay can pull Bombora or 6sense data into a table, enrich it, and push enriched rows to Salesforce or a sequencing tool. It’s a good fit for batch outbound prospecting runs (weekly, not real-time). It’s not a good fit for the real-time notification pattern — Clay tables are not event-driven, so the workflow always has some batch lag. Use Clay for the prospecting layer; use this flow for the real-time spike response layer.
# Intent spike handler — n8n flow
This bundle contains a complete n8n workflow that catches account-level intent spikes from Common Room, 6sense (via Salesforce CRM sync), and Bombora (via Salesforce CRM sync), deduplicates within a day-level window, looks up the Salesforce account owner, assigns the spike to the right rep or SDR pool by territory, drafts a first-touch message with Claude, posts a Slack notification to the assignee, and creates a Salesforce Task with full context.
Two entry points:
- **Real-time path** — `Webhook — Intent Spike Ingest` accepts `POST /webhook/intent-spike-handler` from Common Room outgoing webhooks (or any system that can POST a structured payload).
- **Polling path** — `Polling Cron — Every 4h` queries Salesforce every 4 hours for Accounts modified with Decision/Purchase buying stage (6sense) or high Bombora surge, then forwards each as a self-POST to the ingest webhook.
## What this flow does
The webhook normalizes multi-source intent payloads (Common Room organization shape, 6sense CRM-sync shape, Bombora CRM-sync shape) into a single internal record. A day-level dedup check prevents the same account from firing multiple times in a day — a direct response to the reality that intent platforms re-evaluate scores on short windows and will otherwise flood reps with repeat notifications for the same signal. The dedup window is set at day-level (not hour-level) because the relevant question is not "did the score tick up again?" but "has this rep been notified today?"
Dedup runs entirely inside one Code node (`Dedup Gate (Static Data)`) using n8n's workflow static data — `$getWorkflowStaticData('global')`. That is the only correct way to persist cross-execution state from a Code node: n8n's public REST API has **no** static-data resource, so an HTTP-based approach would 404 and the gate would never fire. The node reads/writes a `dedup_<domain>_<date>` key, prunes keys from previous days on every run (so the store stays small), and stamps the key before any external call so two concurrent spikes for the same domain can't both pass. Important: workflow static data only persists for **production** executions (webhook / Schedule Trigger) — not manual test runs — so dedup is verified live (see step 2 below), not via the manual Execute Workflow button.
Assignment logic prioritizes the existing Salesforce Account owner. If no Account exists, the spike routes to a territory-based SDR pool (AMER, EMEA, ROW) configured via environment variables. Claude generates a three-part draft: a subject line, a short outreach body anchored to the specific topics the account is researching, and a talking point for the SDR's call prep. The draft is explicitly labeled a starting point in the Slack message — it ships as prose the rep edits, not as a send-ready email.
## Import
1. In n8n, open **Workflows → Import from File** and select `intent-spike-handler-n8n.json`.
2. Open the workflow's **Settings** and confirm `Execution Order` is `v1` and `Timezone` is set to match your business hours (defaults to `America/New_York`). The cron interprets its schedule in this zone. The dedup window rolls over at UTC midnight (the key uses the UTC date); if you need it aligned to a local business day, change the date derivation in `Dedup Gate (Static Data)` to use the workflow timezone.
3. Set the environment variables listed in the **Environment variables** section below.
4. Wire all four credentials listed in the **Credentials** section.
5. Create the three Salesforce custom fields listed in the **Salesforce custom fields** section.
6. Activate the workflow only after the first-run verification below passes.
## Environment variables
Set these in your n8n instance's environment (n8n Cloud: **Settings → Environment Variables**; self-hosted: your `.env` file or container environment):
| Variable | Where to find it | Example |
|---|---|---|
| `N8N_SELF_URL_HOST` | Your n8n instance's public hostname, no trailing slash. Used by the polling path to self-POST forwarded spikes to the ingest webhook. | `n8n.example.com` |
| `SFDC_INSTANCE_URL` | Salesforce Setup → Company Information → Salesforce.com Base URL | `https://yourorg.my.salesforce.com` |
| `SFDC_ACCESS_TOKEN` | From your Salesforce connected app OAuth flow | `00D…` |
| `SDR_POOL_AMER_EMAIL` | SDR pool lead email for AMER territory | `sdr-amer@yourcompany.com` |
| `SDR_POOL_AMER_SLACK` | Slack handle (no @) for AMER SDR pool | `sdr-amer` |
| `SDR_POOL_EMEA_EMAIL` | SDR pool lead email for EMEA territory | `sdr-emea@yourcompany.com` |
| `SDR_POOL_EMEA_SLACK` | Slack handle (no @) for EMEA SDR pool | `sdr-emea` |
| `SDR_POOL_ROW_EMAIL` | SDR pool lead email for ROW territory | `sdr-row@yourcompany.com` |
| `SDR_POOL_ROW_SLACK` | Slack handle (no @) for ROW SDR pool | `sdr-row` |
The `SFDC_ACCESS_TOKEN` rotates. For production, use a Connected App with OAuth 2.0 client credentials flow and a short-lived token refresh node, or use the Salesforce OAuth2 credential in n8n instead of the raw Bearer token approach.
## Credentials
### `PLACEHOLDER_ANTHROPIC_CRED_ID` — Anthropic
Used by `Claude — Draft First Touch`. Generate an API key at `https://console.anthropic.com`. In n8n, add an **HTTP Header Auth** credential with header name `x-api-key` and value set to the key. The node uses `claude-haiku-4-5` to keep the latency under 2 seconds on a typical account payload. Swap to `claude-sonnet-4-6` only if draft quality is consistently off for complex industry segments — the cost difference is roughly 10×.
### `PLACEHOLDER_SLACK_CRED_ID` — Slack bot token
Used by `Slack — Notify Assignee`. Create a Slack app at `https://api.slack.com/apps`, add the `chat:write` bot scope, install it to your workspace, and invite the bot user to `#intent-spikes`. In n8n, add an **HTTP Header Auth** credential with header name `Authorization` and value `Bearer xoxb-…`. Create `#intent-spikes` as the landing channel before activating; you can split high-severity spikes to a separate `#intent-spikes-hot` channel by modifying the channel field in `Slack — Notify Assignee`.
### `PLACEHOLDER_SALESFORCE_CRED_ID` — Salesforce Bearer token
Used by `Salesforce — Account Lookup`, `Salesforce — Create Task`, and `Salesforce — Poll Intent Fields`. In n8n, add an **HTTP Header Auth** credential with header name `Authorization` and value `Bearer <your_token>`. For a stable long-running credential, create a Salesforce Connected App with OAuth 2.0 and configure a token refresh; the raw Bearer approach works for initial setup but rotates every 2 hours by default. The credential requires `api`, `read`, `write`, and `chatter_api` OAuth scopes at minimum.
**Task ownership.** When the account lookup finds an existing Account, `Salesforce — Create Task` sets the Task's `OwnerId` to that Account owner's Salesforce **User Id** (a 15/18-char Id starting with `005`), which the lookup returns. Salesforce `OwnerId` does not accept an email address — passing one fails with `MALFORMED_ID`. When no Account is found (the spike routes to a territory SDR pool), `OwnerId` is omitted entirely, so the Task defaults to the user behind this credential (the integration/running user); the intended SDR pool is recorded in the Task Description and the rep is @-mentioned in the Slack notification. To hand these pool Tasks off to a real Salesforce queue or user, add a step that resolves a User/Queue Id (prefix `005`/`00G`) and set `OwnerId` to it.
### `PLACEHOLDER_6SENSE_CRED_ID` / Common Room (for real-time path)
The real-time webhook path accepts payloads from **Common Room outgoing webhooks**. In Common Room, go to **Settings → Webhooks → Add webhook**, set the Payload URL to `https://<your-n8n-host>/webhook/intent-spike-handler`, choose **Organization** as the payload type, and configure a workflow trigger on "contacts meeting criteria" or "new activity" filtered to high-intent signals. No n8n credential is required for this — the webhook is public; optionally verify the `x-commonroom-webhook-secret` header in the `Normalize Intent Payload` node if you add a shared secret.
The polling path uses 6sense and Bombora data **already synced into Salesforce** via those platforms' native managed packages. No direct 6sense or Bombora API credentials are needed in n8n — the Salesforce credential covers the poll.
## Salesforce custom fields
Create these three custom fields on the **Task** object in Salesforce Setup → Object Manager → Task → Fields & Relationships:
| API Name | Field Type | Notes |
|---|---|---|
| `Intent_Spike_Source__c` | Text (50) | Stores `common-room`, `6sense`, `bombora`, or `generic` |
| `Intent_Score__c` | Number (18, 0) | Stores the raw intent score (0–100) |
| `Intent_Buying_Stage__c` | Text (50) | Stores the buying stage string from the source |
The 6sense and Bombora **Account** fields queried by `Salesforce — Poll Intent Fields` are installed by each vendor's managed package. Verify the following API names exist on your Account object before activating the polling path:
- **6sense:** `sixsense_Intent_Score__c`, `sixsense_Buying_Stage__c`, `sixsense_Top_Topics__c`
- **Bombora:** `Bombora_Composite_Score__c`, `Bombora_Surge_Level__c`, `Bombora_Top_Topics__c`
If your managed package uses different API names, update the SOQL query in `Salesforce — Poll Intent Fields` to match.
## First-run verification
Run each path before enabling the cron or wiring Common Room:
**Note on testing dedup:** workflow static data only persists across **production** executions (a real `POST` to the webhook URL, or a Schedule Trigger run), not manual **Execute Workflow** runs. Activate the workflow and `curl` the webhook for steps 1–2 so the dedup key actually persists between the two requests.
1. **High-severity spike (Common Room shape).** `POST` to `https://<your-n8n-host>/webhook/intent-spike-handler` (workflow active) with:
```json
{
"body": {
"type": "organization",
"version": "1",
"name": "Acme Corp",
"domain": "acme-test-spike.com",
"industry": "Software",
"employeeCount": 500,
"location": { "country": "US" },
"technologies": ["Salesforce", "Slack"],
"customFields": {
"sixsense_buying_stage": "Decision",
"sixsense_intent_score": 78,
"sixsense_top_topics": "CRM automation,pipeline management"
}
}
}
```
Expected: dedup passes (no prior key), Slack message lands in `#intent-spikes` with red circle, Salesforce Task created with `Priority: High`, Claude draft present.
2. **Dedup block — same domain same day.** `POST` the identical payload from step 1 a second time (workflow still active). Expected: `Dedup Gate (Static Data)` finds the existing `dedup_acme-test-spike.com_<today>` key and returns an empty array — no Slack message, no Salesforce Task.
3. **Mid-severity spike (Bombora CRM-sync shape).** Send:
```json
{
"_source": "bombora",
"domain": "midco-test-spike.com",
"company_name": "MidCo",
"country": "DE",
"composite_score": 55,
"surge_level": "medium",
"topics": [{ "topic": "data integration" }, { "topic": "ETL tools" }]
}
```
Expected: spike severity maps to `medium`, EMEA SDR pool assigned, yellow circle in Slack.
4. **Claude failure fallback.** Temporarily revoke the Anthropic credential and send any payload. Expected: `Parse Draft (with fallback)` outputs a template-based draft tagged `draftSource: template-fallback`; Slack message and Salesforce Task still fire with the fallback draft.
5. **Polling path.** In Salesforce, set one test Account's `sixsense_Buying_Stage__c` to `Decision` and bump `SystemModstamp` (edit any field and save). Trigger `Polling Cron — Every 4h` manually. Expected: the Account appears in the SOQL results, `Build Forward Payloads` fans it out, `Forward to Ingest Webhook` POSTs it to the main webhook, and the full real-time path runs (dedup key will differ since domain is different from steps 1-4).
Only after all five pass should you enable the workflow and wire Common Room.