Skip to content

Outreach Agent

The Outreach Agent reaches out to priority accounts who have engaged with your website. It filters ICP accounts, identifies decision-makers, and sends personalized cold outreach based on conversation history.

Status

Coming Soon - Data layer available via n8n

Overview

The Outreach Agent provides account-level intelligence for B2B outreach campaigns. It aggregates data across all visitors from a company to help you:

  • Identify high-intent accounts
  • Understand account-level engagement patterns
  • Access all conversation transcripts from the account
  • Prioritize outreach based on intent signals

Data Access

Supabase RPC Function

The agent retrieves data via the get_account_for_outreach_agent RPC function.

Parameters

Parameter Type Required Description
p_site_domain TEXT Yes Your site domain (e.g., "demo.userose.ai")
p_company_domain TEXT Yes Target company domain (e.g., "acme.com")

Example Call

SELECT * FROM get_account_for_outreach_agent('demo.userose.ai', 'acme.com');

n8n Integration

Prerequisites

  1. Database credentials - Get these from your Rose admin:
  2. PostgreSQL host: db.xxx.supabase.co
  3. Database: postgres
  4. User: n8n_service (dedicated read-only user)
  5. Password: Provided by admin
  6. Port: 5432

!!! warning "Do not use Service Role Key" The Service Role Key has full database access. Always use the dedicated n8n_service user which only has execute permission on these specific RPC functions.

  1. n8n PostgreSQL credential - In n8n, go to CredentialsAdd CredentialPostgres and enter the connection details above.

Getting the Company Domain

The company_domain identifies the target account. You can obtain it from:

  • Enrichment services: Clearbit, Apollo, or similar tools that resolve IP to company
  • Rose visitor data: The accounts table stores company domains identified via IP enrichment
  • Manual input: For targeted outreach to specific companies
  • CRM integration: Pull target account domains from your CRM

Step-by-Step Workflow Setup

Option 1: Triggered by New Account Detection

[Webhook from Rose] → [Filter ICP] → [Postgres RPC] → [Send to CRM/Slack]
  1. Add Webhook node as trigger
  2. Configure Rose to send account events to this webhook URL
  3. Fires when a new company is identified visiting your site

  4. Add IF node to filter ICP accounts

  5. Condition: Check company attributes against your ICP criteria

  6. Add Postgres node

  7. Credential: Select your n8n_service Postgres credential
  8. Operation: Execute Query
  9. Query:

    SELECT * FROM get_account_for_outreach_agent(
      'your-site.com',
      '{{ $json.company_domain }}'
    );
    

  10. Add output node (CRM, Slack, Email sequence, etc.)

Option 2: Scheduled Account Review

[Schedule Trigger] → [Postgres Query] → [Loop] → [Postgres RPC] → [Output]
  1. Schedule Trigger: Run daily
  2. Postgres node: Query accounts with high intent scores
  3. Loop: Iterate through each account
  4. Postgres node: Call get_account_for_outreach_agent for each
  5. Output: Push to outreach tool or CRM

Option 3: Manual Account Lookup

[Webhook with company_domain] → [Postgres RPC] → [Return Response]

Useful for sales reps to look up accounts on-demand via Slack command or internal tool.

Postgres Node Configuration

-- n8n Postgres node query
SELECT * FROM get_account_for_outreach_agent(
  '{{ $json.site_domain }}',
  '{{ $json.company_domain }}'
);

Example: CRM Enrichment Workflow

Complete workflow that enriches CRM accounts with Rose intelligence:

[CRM Webhook: Account Updated] → [Supabase RPC] → [Update CRM Account]

CRM field mapping:

{
  "rose_intent_score": "{{ $json.max_intent_score }}",
  "rose_funnel_stage": "{{ $json.funnel_stage }}",
  "rose_visitor_count": "{{ $json.visitor_count }}",
  "rose_topics": "{{ $json.topics.join(', ') }}",
  "rose_last_activity": "{{ $json.last_activity_at }}",
  "rose_total_sessions": "{{ $json.total_sessions }}"
}

Example: Slack Alert for High-Intent Accounts

Slack message template:

🏢 High-Intent Account Alert

*Company:* {{ $json.company_name }} ({{ $json.company_domain }})
*Intent Score:* {{ $json.max_intent_score }}/5
*Funnel Stage:* {{ $json.funnel_stage || 'Browsing' }}
*Visitors:* {{ $json.visitor_count }} people
*Total Sessions:* {{ $json.total_sessions }}
*Engagement:* {{ Math.round($json.total_session_duration_seconds / 60) }} minutes

*Topics of Interest:*
{{ $json.topics.join(', ') }}

*Recent Conversations:*
{{ $json.conversations.slice(0, 3).map(c => '• ' + c.topics.join(', ')).join('\n') }}

Response Fields

Field Type Description
account_id UUID Unique account identifier
company_name TEXT Company name
company_domain TEXT Company domain
visitor_count BIGINT Number of visitors from this account
pages_visited JSONB All unique pages with URL and title (see below)
total_page_views BIGINT Sum of page views across all visitors
total_session_duration_seconds BIGINT Total engagement time (seconds)
total_sessions BIGINT Total sessions across all visitors
funnel_stage TEXT Highest funnel stage reached (see below)
conversations JSONB All conversation transcripts (see below)
topics TEXT[] All topics discussed by account visitors
keywords TEXT[] All keywords from conversations
last_activity_at TIMESTAMPTZ Most recent activity from any visitor
total_messages BIGINT Total messages across all conversations
max_intent_score INTEGER Highest intent score among visitors (1-5)

Funnel Stages

Returns the highest stage reached by any visitor from the account:

Stage Description Trigger
Conversion completed Any visitor booked a demo demo_booked = true
Conversion initiated Any visitor clicked CTA cta_clicked = true
Conversion offered Demo proposed to any visitor demo_proposed = true
null No visitors in conversion funnel No conversion signals

Intent Score

The max_intent_score (1-5) represents the highest intent among all account visitors:

  • 5: Demo booked - Ready to buy
  • 4: CTA clicked - Actively evaluating
  • 3: Demo proposed - Qualified lead
  • 2: Engaged visitor - Showing interest
  • 1: Early stage - Just browsing

Pages Visited JSONB Structure

[
  {
    "url": "/pricing",
    "title": "Pricing - Rose AI"
  },
  {
    "url": "/features/chatbot",
    "title": "AI Chatbot Features"
  }
]

Conversations JSONB Structure

[
  {
    "id": "conversation-uuid",
    "visitor_id": "visitor-uuid",
    "started_at": "2024-01-15T10:30:00Z",
    "topics": ["pricing", "enterprise"],
    "keywords": ["API", "integration"],
    "messages": [
      {
        "role": "user",
        "content": "What's your enterprise pricing?",
        "created_at": "2024-01-15T10:30:00Z"
      },
      {
        "role": "assistant",
        "content": "Our enterprise plans start at...",
        "created_at": "2024-01-15T10:30:05Z"
      }
    ]
  }
]

Security

Webhook Authentication Required

If your n8n workflow is triggered by a webhook, you MUST add authentication to prevent unauthorized access. Without authentication, anyone who discovers your webhook URL can trigger the workflow and access your data.

Options:

  • Header Auth: Require a secret token in Authorization header
  • Query Param Auth: Require a secret in the URL (less secure)
  • IP Allowlist: Restrict to known IPs (e.g., PostHog servers)

Read-Only Access

The RPC functions are read-only (STABLE in PostgreSQL terms). They cannot modify any data.

Tenant Isolation

The p_site_domain parameter ensures data isolation:

  • Each call is scoped to a specific site domain
  • Users can only access data for sites they own
  • No cross-tenant data access is possible

Supabase Role Configuration

See Lead Intelligence Agent - Security for detailed setup instructions.

Summary: Use a dedicated n8n_readonly PostgreSQL role with minimal permissions:

-- Create role and user (run once)
CREATE ROLE n8n_readonly NOLOGIN;
GRANT EXECUTE ON FUNCTION get_account_for_outreach_agent(TEXT, TEXT) TO n8n_readonly;
GRANT EXECUTE ON FUNCTION get_visitor_for_lead_intelligence(TEXT, TEXT) TO n8n_readonly;

CREATE USER n8n_service WITH PASSWORD 'your-secure-password-here';
GRANT n8n_readonly TO n8n_service;

Then connect n8n using the PostgreSQL node with n8n_service credentials.

Method Use Case Risk Level
PostgreSQL with n8n_service n8n integrations (recommended) Low - Only RPC execute permission
Supabase with Anon Key Quick setup, less secure Low-Medium
Service Role Never use externally High - Full database access

Use Cases

  1. Account-based outreach: Personalize cold emails using conversation context
  2. ICP prioritization: Filter accounts by intent score and engagement
  3. Multi-threaded selling: Identify all engaged visitors from a target account
  4. Competitive intelligence: Understand what topics/features accounts care about