Skip to main content

Build an AI Lead Qualification Bot in 45 Minutes (OpenClaw Tutorial) [2026]

· 9 min read
MarketBetter Team
Content Team, marketbetter.ai

Every minute a hot lead waits for a response, your conversion rate drops by 7%. But you can't have SDRs working 24/7—or can you?

This guide walks you through building an AI-powered lead qualification bot using OpenClaw that works around the clock: asking the right questions, scoring leads in real-time, and instantly routing qualified prospects to your sales team.

Lead qualification bot architecture showing leads flowing through automated scoring and routing

Why Lead Qualification Bots Win

The math is brutal:

  • 78% of deals go to the company that responds first
  • Average response time for web leads: 47 hours
  • Lead conversion drops 80% after the first 5 minutes

Traditional chatbots don't solve this. They're glorified FAQ systems that frustrate prospects with "I'll have someone contact you." By the time someone contacts them, they've already booked a demo with your competitor.

An AI qualification bot does real work:

Traditional ChatbotAI Qualification Bot
"Someone will contact you"Asks qualifying questions in real-time
Static decision treesDynamic conversation flow
Routes all leads equallyScores and prioritizes automatically
No context awarenessRemembers previous interactions
9-5 availabilityTrue 24/7 qualification

The OpenClaw Advantage

Why OpenClaw for lead qualification?

  1. Always-on operation — Cron jobs keep your bot responsive 24/7
  2. Memory persistence — Bot remembers conversation context across sessions
  3. Multi-channel — Works on website chat, WhatsApp, Slack, or wherever leads arrive
  4. Browser automation — Can research leads in real-time (check LinkedIn, company website)
  5. CRM integration — Direct HubSpot, Salesforce, and API connections
  6. Free and self-hosted — No per-conversation pricing that scales badly

Let's build it.

Step 1: Define Your Qualification Criteria

Before writing any code, define what makes a qualified lead for your business.

BANT Framework (Classic)

  • Budget: Can they afford your solution?
  • Authority: Are they a decision-maker?
  • Need: Do they have a problem you solve?
  • Timeline: When are they looking to buy?

Modern Qualification Criteria

For most B2B SaaS, focus on:

qualification_criteria:
must_have:
- Company size: 50-500 employees
- Role: Director+ in Sales, Marketing, or RevOps
- Use case: Lead generation or SDR efficiency
- Timeline: Active evaluation (next 3 months)

nice_to_have:
- Using competitor: Apollo, 6sense, ZoomInfo
- Pain point: SDR productivity or lead quality
- Trigger event: New funding, hiring SDRs

disqualifiers:
- Company size: <20 employees
- No budget authority
- Looking for free tools only
- Student/job seeker

Scoring Matrix

CriteriaPointsWeight
Director+ role+20High
50-500 employees+15High
Active evaluation+25Critical
Using competitor+15Medium
Pain match+20High
Budget confirmed+30Critical
Timeline &lt;3 months+20High
Student/researcher-100Disqualify

Score thresholds:

  • 0-30: Nurture (add to email sequence)
  • 31-60: Qualified (route to SDR)
  • 61+: Hot (route to AE, alert Slack)

Step 2: Create the OpenClaw Agent

Set up your qualification bot in OpenClaw's AGENTS.md:

# lead-qualifier agent config
name: lead-qualifier
model: claude-sonnet-4-20250514
channels:
- webchat
- whatsapp

memory:
- QUALIFICATION_RULES.md
- ICP.md

cron:
# Check for new leads every minute
- schedule: "* * * * *"
task: "Check for new unqualified leads in CRM and initiate qualification"

Step 3: The Qualification Conversation Flow

Here's the soul of your bot—the qualification prompt:

# QUALIFICATION_RULES.md

You are a friendly, professional lead qualification specialist for MarketBetter.
Your job is to have natural conversations that qualify leads while being helpful.

## CONVERSATION RULES

1. NEVER sound like a bot. Be conversational and human.
2. Ask ONE question at a time. Don't interrogate.
3. If they ask product questions, answer them—then continue qualifying.
4. Match their communication style (casual/formal).
5. If they're clearly not a fit, be respectful and offer resources.

## QUALIFICATION QUESTIONS

Ask these naturally throughout the conversation (not all at once):

1. **Company/Role**: "What company are you with? And what's your role there?"
2. **Team size**: "How big is your sales/SDR team currently?"
3. **Pain point**: "What brought you to MarketBetter today? What are you trying to solve?"
4. **Current tools**: "What tools are you using today for [their pain point]?"
5. **Timeline**: "Are you actively evaluating solutions, or just researching for now?"
6. **Budget**: "Do you have budget allocated for this, or would this be a new initiative?"

## SCORING (internal, don't share with lead)

After each response, update your internal score:
- Director/VP/C-level: +20
- 50-500 employees: +15
- 10-50 SDRs: +10
- Pain point matches our ICP: +20
- Active evaluation: +25
- Using competitor: +15
- Budget confirmed: +30
- Timeline < 3 months: +20

Disqualify immediately if:
- Student/researcher
- Company < 20 employees
- No commercial intent
- Competitor employee

## ROUTING ACTIONS

Score 0-30 (Nurture):
- Thank them warmly
- Offer to add to newsletter for tips
- Create lead in CRM as "Marketing Qualified"

Score 31-60 (Qualified):
- Offer to schedule a call with an SDR
- Use Calendly link: [link]
- Create opportunity in CRM

Score 61+ (Hot):
- Immediately alert Slack channel #hot-leads
- Offer to connect them with AE now
- Create high-priority task for AE

## EXAMPLE CONVERSATION

Lead: "Hi, I'm looking at lead generation tools"

You: "Hey! Happy to help. I'm Alex from MarketBetter.
What's got you looking at lead gen tools right now—any specific challenge you're trying to solve?"

Lead: "Our SDR team is spending too much time researching leads"

You: "Ah, that's a super common one. How big is your SDR team? Just trying to get a sense of the scale."

Lead: "We have about 15 SDRs"

You: "Got it—15 SDRs is a solid team. And you mentioned research is eating up their time...
are you using any tools today for lead research, or is it mostly manual?"

[Continue naturally until qualified]

Lead scoring funnel showing leads entering and being scored into hot, qualified, and nurture categories

Step 4: CRM Integration

Connect your bot to your CRM so qualified leads get created automatically:

// In your OpenClaw skills or scripts
const qualifyLead = async (conversation) => {
// Extract qualification data from conversation
const qualData = await claude.analyze({
prompt: `Extract qualification data from this conversation:
${conversation}

Return JSON: {
name, email, company, role, teamSize, painPoint,
currentTools, timeline, budgetConfirmed, score, notes
}`
});

// Create/update lead in HubSpot
const lead = await hubspot.createContact({
email: qualData.email,
firstname: qualData.name.split(' ')[0],
lastname: qualData.name.split(' ').slice(1).join(' '),
company: qualData.company,
jobtitle: qualData.role,
lifecyclestage: qualData.score > 30 ? 'salesqualifiedlead' : 'marketingqualifiedlead',
lead_score: qualData.score,
hs_lead_status: qualData.score > 60 ? 'HOT' : 'QUALIFIED',
notes: qualData.notes
});

// Route based on score
if (qualData.score > 60) {
await slack.send('#hot-leads', {
text: `🔥 Hot lead just qualified!`,
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `*${qualData.name}* from *${qualData.company}*\n` +
`Score: ${qualData.score}/100\n` +
`Pain: ${qualData.painPoint}\n` +
`Timeline: ${qualData.timeline}`
}
},
{
type: "actions",
elements: [
{
type: "button",
text: { type: "plain_text", text: "View in HubSpot" },
url: `https://app.hubspot.com/contacts/${lead.id}`
}
]
}
]
});
}

return lead;
};

Step 5: Real-Time Lead Research

Here's where OpenClaw shines—your bot can research leads during the conversation:

// When lead provides company name
const enrichLead = async (companyName) => {
// Use browser to research
const research = await openclaw.browser.research({
queries: [
`${companyName} linkedin company`,
`${companyName} crunchbase funding`,
`${companyName} careers hiring`
]
});

// Claude summarizes findings
const enrichment = await claude.analyze({
prompt: `Summarize this company research for sales qualification:
${research}

Extract: employee count, funding stage, recent news, tech stack hints, hiring signals`
});

return enrichment;
};

Now your bot can say things like:

"Oh nice, I see Acme Corp just raised a Series B—congrats! Are you looking at tools to help scale the team with that new funding?"

This level of personalization makes leads forget they're talking to a bot.

Step 6: Multi-Channel Deployment

Deploy your qualification bot across channels:

Website Chat

Embed OpenClaw's webchat widget on high-intent pages:

  • Pricing page
  • Demo request page
  • Feature comparison pages

WhatsApp Business

For leads who prefer messaging:

# OpenClaw whatsapp channel config
whatsapp:
number: "+1-XXX-XXX-XXXX"
webhook: /api/whatsapp
qualify_on: first_message

Slack Connect

For enterprise prospects already in Slack:

slack:
workspace: marketbetter
channel: #shared-[company]
qualify_on: join

Step 7: Handle Edge Cases

Good bots handle the unexpected:

Product Questions Mid-Qualification

## PRODUCT QUESTIONS

If the lead asks product questions during qualification, ANSWER THEM.
Don't deflect with "let me have someone call you."

Use this knowledge base:
- [Link to product docs]
- [Link to feature matrix]
- [Link to pricing info]

After answering, naturally transition back to qualification:
"Does that answer your question? By the way, I want to make sure
I connect you with the right person—what's your role at [company]?"

Impatient Leads

## FAST QUALIFICATION

If lead seems impatient or says "just get me to sales":
- Don't force all questions
- Ask ONLY: company, role, and main use case
- Immediately offer calendar link
- Note in CRM: "Fast-tracked, needs full qualification on call"

Off-Hours Handling

## AFTER HOURS

If it's outside business hours (6pm-8am local):
- Still fully qualify
- Offer next-day call booking
- Set expectation: "Great! [AE name] will reach out first thing tomorrow morning"
- Create high-priority task for morning

Measuring Success

Track these metrics for your qualification bot:

MetricTargetWhy It Matters
Response time&lt;30 secondsSpeed to lead
Qualification rate>40%Bot effectiveness
Handoff acceptance>80%Scoring accuracy
Demo show rate>70%Lead quality
Pipeline influencedTrack monthlyRevenue impact

The MarketBetter Connection

MarketBetter's AI chatbot uses similar qualification intelligence—but goes further by connecting to your entire GTM stack:

  • Website visitor identification to enrich leads before they chat
  • Intent signals from their browsing behavior
  • Seamless handoff to SDR playbook for follow-up
  • Closed-loop reporting on which leads convert

The result? Leads are qualified, scored, and routed in seconds—not hours.

See MarketBetter's AI qualification in action →

Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

Implementation Checklist

Ready to build your qualification bot?

  • Define qualification criteria and scoring
  • Create OpenClaw agent with qualification prompt
  • Set up CRM integration (HubSpot/Salesforce)
  • Configure Slack alerts for hot leads
  • Deploy to website chat
  • Add WhatsApp channel (optional)
  • Set up lead enrichment research
  • Configure off-hours handling
  • Test with sample conversations
  • Monitor and tune scoring thresholds

The best SDRs still beat bots in complex sales conversations. But for initial qualification? A well-built AI bot responds faster, works 24/7, and never forgets to ask the important questions.


Building more AI automation for GTM? Check out our guides on CRM hygiene automation and the complete OpenClaw setup guide.

Claude LinkedIn Outreach: Automate Personalized Messages Without Getting Banned [2026]

· 11 min read
MarketBetter Team
Content Team, marketbetter.ai

LinkedIn is where B2B deals start.

Your best prospects are there. Decision-makers scroll it daily. A well-crafted message can open doors that cold email never could.

But here's the problem: personalization doesn't scale.

You can either send 100 generic messages (and get ignored) or send 10 deeply personalized ones (and miss 90% of your prospects).

Claude Code changes that equation.

This guide shows you how to build an AI-powered LinkedIn outreach system that researches prospects deeply, crafts genuinely personalized messages, and sequences follow-ups—all while staying within LinkedIn's terms of service.

Wondering whether Claude can plug into LinkedIn directly? It can't — there is no native connector, and the workarounds carry very different risk levels. We break down all three options in Can Claude connect to LinkedIn? before you commit to a workflow.

LinkedIn outreach automation workflow with AI personalization

Why Most LinkedIn Outreach Fails

Before we build the solution, let's understand the problem:

The Generic Message Problem

Hi [Name],

I noticed we're both in the [Industry] space. I'd love to connect
and learn more about what you're working on at [Company].

Best,
[SDR Name]

Every decision-maker sees this 50 times a day. The acceptance rate? Under 5%.

The "I Checked Your Profile for 2 Seconds" Problem

Hi Sarah,

I see you're the VP of Sales at Acme Corp—impressive background!
I'd love to share how we help sales leaders like you...

The prospect knows you didn't really research them. You just read their headline. This performs marginally better than full generic, but still gets ignored.

The Actually Personalized Message

Hi Sarah,

Caught your comment on Mark Roberge's post about PLG motions last week.
The point about enterprise sales teams struggling to adapt to product-led
signals resonated—we see the same pattern with our customers in IoT.

Curious how you're handling that transition at Acme, especially
after the Globex acquisition. Happy to share what's working for
companies in similar situations if helpful.

No pitch, just genuinely interested in your take.

This gets responses. But it took 15 minutes to research and write.

The goal: Get the third message's quality at the first message's scale.

The Claude Code Approach

Claude's 200K context window and nuanced writing make it perfect for this:

  1. Research deeply — Pull prospect's recent posts, comments, company news
  2. Identify angles — Find genuine connection points (not fake ones)
  3. Write naturally — Match the prospect's communication style
  4. Avoid AI tells — No corporate speak, no obvious templates

What You'll Build

By the end of this guide, you'll have a system that:

  • Researches prospects using public LinkedIn data
  • Identifies personalization hooks from their activity
  • Generates connection request messages (300 char limit)
  • Creates follow-up sequences based on profile type
  • Tracks sent messages and responses

Step 1: Prospect Research with Claude

First, gather intelligence. You need:

  • Recent posts and comments
  • Company news
  • Shared connections
  • Background/experience

Building the Research Prompt

// prospect-research.js
const researchPrompt = `You are a sales research assistant.
Given information about a LinkedIn prospect, identify:

1. **Recent Activity Hooks**
- Posts they've written (topics, opinions expressed)
- Comments on others' posts (what caught their attention)
- Articles shared (what they find valuable)

2. **Company Context**
- Recent news (funding, acquisitions, product launches)
- Likely challenges given their industry/stage
- Competitor activity they'd care about

3. **Personal Connection Points**
- Shared experiences (schools, past companies, interests)
- Mutual connections worth mentioning
- Career transitions that show priorities

4. **Communication Style**
- Formal vs casual tone
- Direct vs relationship-first
- Technical vs business-focused

Return a JSON object with these categories and specific examples.
Only include REAL information—never fabricate details.
If you can't find something, say "Not found" rather than guessing.`;

Gathering Public Data

Use Claude Code to build a research aggregator:

codex "Create a prospect research function that:

1. Takes a LinkedIn profile URL or name + company
2. Searches for their recent public posts using web search
3. Finds recent company news
4. Identifies mutual connections from a provided list
5. Returns structured research data

Use Brave Search API for web searches.
Parse LinkedIn public profiles (no scraping private data).
Respect rate limits and don't hammer any single source."

LinkedIn profile analysis and personalized message generation

Step 2: Message Generation

Now the magic—turning research into messages:

Connection Request Messages

LinkedIn limits connection requests to 300 characters. Every word counts.

const connectionRequestPrompt = `Write a LinkedIn connection request 
based on this prospect research:

{{research}}

CONSTRAINTS:
- Maximum 300 characters (including spaces)
- No salesy language
- Reference ONE specific thing from their activity
- End with a reason to connect, not a pitch
- Match their communication style (see research)

EXAMPLES OF GOOD MESSAGES:

"Your comment on the PLG debate resonated—we're seeing similar
tension between product-led and sales-led at IoT companies.
Would love to compare notes."

"Saw Acme's Series C announcement—congrats! Curious how you're
thinking about scaling the sales team. Happy to share patterns
from similar stage companies."

"Your post about SDR burnout hit home. Building tools to help
with exactly that. Would value your perspective."

Write 3 options ranked by quality. Explain why each works.`;

First Follow-Up Messages

After they accept, the first message sets the tone:

const firstFollowUpPrompt = `Write a follow-up message for a 
prospect who just accepted my connection request.

Original connection request:
{{original_message}}

Prospect research:
{{research}}

GUIDELINES:
- Thank them for connecting (briefly, not effusively)
- Expand on the topic from the connection request
- Offer specific value (insight, introduction, resource)
- End with a soft question, not a meeting request
- Keep under 500 characters

The goal is to start a conversation, not close a meeting.`;

Step 3: Sequence Building

Different prospects need different sequences:

Decision Maker Sequence

const dmSequence = {
day0: 'connection_request',
day3: 'first_followup',
day7: 'value_message', // Share relevant content
day14: 'soft_ask', // Suggest a call if engaged
day21: 'breakup' // Graceful close
};

const valueMessagePrompt = `Create a value-add message for this prospect.

Research: {{research}}
Previous messages: {{thread}}

Find ONE piece of content (post, article, report) that would
genuinely help them. Explain briefly why it's relevant to
their specific situation.

NOT: "Here's our latest whitepaper"
YES: "This analysis of PLG sales models reminded me of your
comment about enterprise motion challenges. Section 3 on
hybrid approaches might be relevant for Acme's situation."

Keep under 400 characters.`;

IC (Individual Contributor) Sequence

const icSequence = {
day0: 'connection_request',
day2: 'peer_followup', // More casual, peer-to-peer
day5: 'resource_share', // Tool, template, or tip
day10: 'dm_intro_ask' // Ask for intro if there's a DM target
};

Step 4: Automating the Pipeline

Bring it together with OpenClaw for scheduling:

Daily Research Job

# openclaw config
cron:
- name: "LinkedIn Research"
schedule: "0 6 * * 1-5" # 6am weekdays
task: |
For each prospect in my outreach queue:
1. Run research function
2. Generate appropriate message
3. Queue for sending
4. Log to tracking sheet

Message Queue and Tracking

codex "Create a LinkedIn outreach tracker that:

1. Maintains a queue of prospects to contact
2. Tracks sent messages and dates
3. Logs responses and engagement
4. Calculates acceptance and reply rates
5. Alerts when a prospect engages

Store in Supabase with these fields:
- prospect_id, name, company, title
- research_json
- messages_sent (array with dates)
- status (queued/sent/accepted/replied/converted)
- notes

Generate weekly report showing:
- Messages sent, accepted, replied
- Best-performing message templates
- Prospects needing follow-up"

Real Performance Numbers

When you implement AI-assisted LinkedIn outreach properly:

Generic Approach

  • Connection acceptance: 5-10%
  • Reply rate: 2-5%
  • Meeting rate: 0.5-1%

AI-Personalized Approach

  • Connection acceptance: 35-50%
  • Reply rate: 15-25%
  • Meeting rate: 5-10%

That's a 10x improvement in meetings booked.

Sample Week

DayProspects ResearchedMessages SentAcceptedRepliedMeetings
Mon2020831
Tue2020941
Wed2020730
Thu20201052
Fri2020841
Total10010042195

Five meetings from 100 prospects, with maybe 2 hours of actual work (review and approve messages).

Avoiding LinkedIn Jail

LinkedIn's algorithms detect automation. Here's how to stay safe:

Activity Limits

  • Connection requests: 20-25/day max
  • Messages: 50-75/day max
  • Profile views: 100-150/day max
  • Searches: Spread throughout the day

Human Patterns

  • Don't send at exactly the same time daily
  • Vary message lengths
  • Take weekends off (mostly)
  • Accept requests manually sometimes

Quality Signals

LinkedIn rewards engagement:

  • Post your own content weekly
  • Comment thoughtfully on others' posts
  • Complete your profile fully
  • Have a reasonable network size

Red Flags to Avoid

  • Identical messages to multiple people
  • Sending from a brand new account
  • Mass connection requests in short bursts
  • Never posting your own content

Integrating with Your Sales Stack

LinkedIn outreach works best when integrated:

CRM Sync

codex "Create a HubSpot integration that:

1. Creates/updates contacts when LinkedIn connections accept
2. Logs LinkedIn messages as activities
3. Updates deal stage when replies indicate interest
4. Triggers sales sequences for qualified prospects"

Routing to AEs

When a prospect engages:

  1. Research reply — Check sentiment, interest level
  2. Update CRM — Add notes on what they said
  3. Notify AE — Slack alert with context
  4. Queue handoff message — Draft intro from SDR to AE

Pro Tips from Top Performers

Tip 1: Engage Before Connecting

Before sending a connection request:

  • Like 2-3 of their posts
  • Leave a thoughtful comment
  • Share something of theirs with your take

Now when you connect, they recognize your name.

Tip 2: Use Their Words

If they wrote a post about "sales efficiency," use that exact phrase. If they call themselves a "revenue leader" not a "sales leader," mirror that.

Claude is great at this when you provide the source material.

Tip 3: Give Before Asking

The ratio should be 3:1 — three value-adds for every ask:

  1. Connection request (light ask)
  2. Useful article/insight (give)
  3. Relevant introduction (give)
  4. Industry tip (give)
  5. Meeting request (ask)

Tip 4: Warm Up the DM

Your best prospects probably follow influencers in your space. Engage with those influencers' content where your prospects are commenting.

Now you've "met" in public before sliding into DMs.

Common Mistakes to Avoid

Over-Relying on AI

AI generates the message, but you should:

  • Review every message before sending
  • Add personal touches you genuinely know
  • Skip prospects where you can't find real hooks
  • Adjust based on responses

Fake Personalization

# BAD
"I see you're passionate about sales—me too!"

# GOOD
"Your post last week about discounting during
enterprise negotiations changed how I think
about pricing conversations."

If you can't find real personalization, use a honest generic:

"Expanding my network of sales leaders in IoT. 
Your background at [Company] caught my eye.
Happy to connect and share what I'm seeing
in the space."

Honest generic beats fake personal every time.

Pitching Too Soon

The sequence matters:

  1. Connect
  2. Acknowledge
  3. Provide value
  4. Ask

Skipping to step 4 kills the relationship.

Getting Started This Week

Day 1: Set Up Tools

  • Install Claude Code / Codex CLI
  • Set up tracking spreadsheet or Supabase table
  • Create your prospect list (50 targets)

Days 2-3: Build Research Flow

  • Create research prompt
  • Test on 5 prospects manually
  • Refine based on what's useful

Days 4-5: Generate Messages

  • Create message prompts for each sequence step
  • Generate messages for 20 prospects
  • Review and improve prompt

Week 2: Launch

  • Send 10-15 connection requests daily
  • Track acceptance and reply rates
  • Iterate on messages based on performance

Next Steps

LinkedIn outreach is just one piece of the prospecting puzzle. To see how AI-powered outreach fits into a complete SDR workflow:

Book a MarketBetter demo — We'll show you how the Daily SDR Playbook combines LinkedIn signals, email outreach, and CRM data to tell your reps exactly who to contact and what to say.

Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.


The best LinkedIn outreach doesn't feel like outreach. It feels like a human who did their homework. Now you can do that homework in seconds.

Multi-Channel Sequence Orchestration with OpenClaw: Email + LinkedIn + Calls [2026]

· 8 min read
MarketBetter Team
Content Team, marketbetter.ai

The best sales sequences aren't single-channel. They're coordinated attacks across email, LinkedIn, and phone—timed perfectly based on prospect behavior.

But managing multi-channel sequences manually? Chaos. You're toggling between 4 tools, copy-pasting data, and hoping you don't accidentally call someone you just emailed. Or worse—reaching out on LinkedIn after they already replied to your email.

OpenClaw changes this. As an open-source AI gateway, it can orchestrate touchpoints across every channel, making decisions in real-time based on prospect response. No more rigid "Day 1 email, Day 3 LinkedIn" sequences. Instead: intelligent orchestration that adapts.

Multi-Channel Orchestration

The Problem with Linear Sequences

Traditional multi-channel sequences look like this:

Day 1: Email #1
Day 3: LinkedIn connection request
Day 5: Email #2
Day 7: Phone call
Day 10: Email #3
Day 14: LinkedIn message

The problems:

  1. Ignores responses - Prospect replies on Day 2? Sequence keeps blasting.
  2. No channel preference detection - Some people live on LinkedIn, others on email
  3. Rigid timing - Day 5 might be a holiday or their busiest day
  4. Coordination gaps - Your dialer doesn't know what your email tool sent
  5. Manual overrides - Reps spend more time managing the sequence than selling

AI orchestration solves these by making real-time decisions:

Day 1: Email #1
→ If reply: Stop sequence, alert rep
→ If LinkedIn engagement: Prioritize LinkedIn next
→ If website visit: Trigger call immediately

Day 3: [Conditional]
→ If email opened 3x: Send email #2
→ If no email engagement: Try LinkedIn
→ If already connected on LinkedIn: Direct message

Building an Orchestration Engine with OpenClaw

Here's the architecture:

┌─────────────────────────────────────────────────────────┐
│ PROSPECT ENTERS │
│ (new lead from any source) │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ INITIAL RESEARCH │
│ Claude enriches: title, company size, social presence │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ CHANNEL PREFERENCE SCORING │
│ - LinkedIn active? (posts, engagement) │
│ - Email deliverable? (bounce risk) │
│ - Phone available? (direct dial vs. HQ) │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ ORCHESTRATION ENGINE │
│ OpenClaw decides: which channel, what message, when │
└─────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ EMAIL │ │ LINKEDIN│ │ PHONE │
└─────────┘ └─────────┘ └─────────┘
│ │ │
└────────────────────┴────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ RESPONSE MONITORING │
│ - Email opens/clicks/replies │
│ - LinkedIn accepts/views/responds │
│ - Call outcomes (connected, VM, callback requested) │
└─────────────────────────────────────────────────────────┘


[Loop back to orchestration engine]

Channel Sequence Icons

Implementation: Step by Step

Step 1: Define Your Sequence Logic

Create a sequence configuration that OpenClaw can execute:

# sequence-config.yaml
name: "Enterprise Outbound"
target: "VP/Director Sales @ B2B SaaS 100-500 employees"

stages:
- name: "initial_outreach"
duration: "3 days"
actions:
- channel: "email"
template: "cold_intro_v2"
priority: 1
- channel: "linkedin_connect"
note_template: "connection_note"
priority: 2
condition: "has_linkedin_profile"

exit_conditions:
- type: "reply"
next_stage: "conversation"
- type: "meeting_booked"
next_stage: "complete"

- name: "follow_up"
duration: "7 days"
entry_condition: "no_response_after_initial"
actions:
- channel: "email"
template: "follow_up_value_add"
delay: "2 days"
condition: "email_opened_count >= 2"
- channel: "linkedin_message"
template: "linkedin_follow_up"
delay: "2 days"
condition: "linkedin_connected"
- channel: "phone"
script: "discovery_call_script"
delay: "3 days"
priority: 1
condition: "has_direct_phone"

- name: "nurture"
entry_condition: "no_response_after_follow_up"
actions:
- channel: "email"
template: "content_share"
frequency: "weekly"
max_attempts: 4

Step 2: Build the Orchestration Agent

// orchestration-agent.js

const OpenClaw = require('openclaw');

const agent = new OpenClaw.Agent({
name: 'Sequencer',
triggers: ['prospect_added', 'response_received', 'daily_check']
});

agent.on('prospect_added', async (prospect) => {
// Enrich prospect data
const enriched = await enrichProspect(prospect);

// Score channel preferences
const channels = await scoreChannelPreferences(enriched);

// Start sequence
await startSequence(prospect.id, 'enterprise_outbound', channels);
});

agent.on('response_received', async (event) => {
const { prospectId, channel, responseType } = event;

if (responseType === 'reply' || responseType === 'meeting_booked') {
// Stop automated sequence
await pauseSequence(prospectId);

// Alert assigned rep
await notify.slack({
channel: '#hot-leads',
message: `🎯 ${event.prospectName} responded via ${channel}!`
});

// Create follow-up task
await createTask(prospectId, 'respond_to_inquiry', {
priority: 'high',
deadline: '4 hours'
});
}

if (responseType === 'engagement') {
// Engagement but no response - adjust strategy
await adjustSequence(prospectId, {
preferChannel: channel,
increaseFrequency: true
});
}
});

agent.on('daily_check', async () => {
const activeProspects = await getActiveSequences();

for (const prospect of activeProspects) {
const nextAction = await determineNextAction(prospect);

if (nextAction) {
await scheduleAction(prospect.id, nextAction);
}
}
});

Step 3: Channel Preference Scoring

Not all prospects respond equally to each channel:

async function scoreChannelPreferences(prospect) {
const scores = {
email: 50, // Base score
linkedin: 50,
phone: 50
};

// LinkedIn activity signals
if (prospect.linkedin_posts_last_90_days > 5) {
scores.linkedin += 25; // Active on LinkedIn
}
if (prospect.linkedin_engagement_score > 70) {
scores.linkedin += 15;
}
if (!prospect.linkedin_profile) {
scores.linkedin = 0; // Can't use what doesn't exist
}

// Email signals
if (prospect.email_bounce_risk === 'high') {
scores.email -= 30;
}
if (prospect.previous_email_opens > 0) {
scores.email += 20; // Has opened our emails before
}
if (prospect.company_size > 1000) {
scores.email -= 10; // Enterprise = more gatekeeping
}

// Phone signals
if (prospect.has_direct_dial) {
scores.phone += 30;
}
if (prospect.has_mobile) {
scores.phone += 20;
}
if (prospect.title.includes('C-level')) {
scores.phone -= 15; // Harder to reach
scores.linkedin += 15; // But responsive on LinkedIn
}

return scores;
}

Step 4: Smart Timing

Don't just blast—time it right:

async function determineOptimalSendTime(prospect, channel) {
// Time zone awareness
const prospectTz = prospect.timezone || await inferTimezone(prospect.location);

// Historical engagement data
const engagement = await getEngagementHistory(prospect.id);

// Find optimal window
if (channel === 'email') {
// Best open rates: Tue-Thu, 9-11am local
return findNextWindow(prospectTz, {
preferredDays: [2, 3, 4], // Tue, Wed, Thu
preferredHours: [9, 10, 11],
avoidHours: [12, 13] // Lunch
});
}

if (channel === 'phone') {
// Best connect rates: early morning or end of day
// But respect Do Not Call hours
return findNextWindow(prospectTz, {
preferredHours: [8, 9, 16, 17],
avoidHours: [12, 13],
respectDNC: true
});
}

if (channel === 'linkedin') {
// LinkedIn engagement peaks: breakfast, lunch, commute
return findNextWindow(prospectTz, {
preferredHours: [7, 8, 12, 18, 19]
});
}
}

Step 5: Response Handling

The magic happens when prospects respond:

// Response handler
async function handleResponse(event) {
const { prospect, channel, content, sentiment } = event;

// Analyze response with Claude
const analysis = await claude.analyze({
prompt: `Analyze this sales response and classify:

Response: "${content}"

Categories:
- POSITIVE: Interested, wants to learn more
- NEGATIVE: Not interested, timing not right
- REFERRAL: Suggests talking to someone else
- QUESTION: Has questions, needs info
- OOO: Out of office / automated reply

Also extract: any mentioned dates, preferences, or objections.`
});

switch (analysis.category) {
case 'POSITIVE':
await pauseSequence(prospect.id);
await createTask('schedule_call', {
prospect,
urgency: 'high',
context: analysis.extractedInfo
});
break;

case 'NEGATIVE':
await endSequence(prospect.id, 'not_interested');
await scheduleNurture(prospect.id, '90 days');
break;

case 'REFERRAL':
await createReferralLead(analysis.referredPerson);
await sendThankYou(prospect);
break;

case 'QUESTION':
await pauseSequence(prospect.id);
await createTask('answer_question', {
prospect,
question: analysis.extractedInfo.question
});
break;

case 'OOO':
const returnDate = analysis.extractedInfo.returnDate;
await pauseSequenceUntil(prospect.id, returnDate);
break;
}
}

Real-World Sequence Example

Here's a complete sequence that adapts:

PROSPECT: Sarah Chen, VP Sales at TechCorp (450 employees)

Day 1, 9:04am EST
→ Channel preference: LinkedIn (83), Email (71), Phone (65)
→ Action: Email intro sent (personalized to B2B SaaS pain points)

Day 1, 2:15pm EST
→ Signal: Email opened (mobile device)
→ Decision: Wait for click/reply before next action

Day 2, 8:30am EST
→ Signal: Email opened again, clicked pricing link
→ Decision: Accelerate LinkedIn connection

Day 2, 9:12am EST
→ Action: LinkedIn connection request sent

Day 2, 3:45pm EST
→ Signal: LinkedIn accepted
→ Decision: Send LinkedIn message (more personal than email)

Day 3, 8:05am EST
→ Action: LinkedIn message sent (referenced pricing visit)

Day 3, 11:30am EST
→ Signal: LinkedIn message read, no reply
→ Decision: Give breathing room, prepare phone call

Day 4, 4:15pm EST
→ Action: Phone call attempted
→ Outcome: Voicemail left

Day 5, 9:30am EST
→ Signal: Website visit (case studies page)
→ Decision: Send value-add email with case study

Day 5, 9:45am EST
→ Action: Email sent (case study)

Day 5, 10:22am EST
→ Signal: Email reply! "This looks interesting. Can we talk Thursday?"
→ Decision: STOP sequence, create booking task

Day 5, 10:25am EST
→ Task created: "Schedule call with Sarah Chen - Thursday"
→ Sequence status: PAUSED - Conversation active

Metrics That Matter

Track these to optimize your sequences:

MetricWhat It MeasuresTarget
Multi-touch response rate% responding to any channel>15%
Channel conversion by stageWhich channel drives replies at each stageVaries
Optimal touch countAverage touches before response&lt;6
Sequence completion rate% who finish without response&lt;70%
Response timeHow fast you follow up on replies&lt;4 hrs

Integration with MarketBetter

If you're using MarketBetter, multi-channel orchestration is built in:

  • Daily SDR Playbook automatically sequences touches
  • Smart Dialer knows what emails/LinkedIn you've sent
  • Unified timeline shows all touchpoints in one view
  • AI prioritization decides which prospect needs which channel next

No need to build from scratch—just configure your sequence rules and let the platform orchestrate.

Free Tool

Try our Marketing Plan Generator — generate a complete AI-powered marketing plan in minutes. No signup required.

Conclusion

Single-channel sequences are relics. In 2026, the winning outbound strategy is coordinated, adaptive, multi-channel orchestration that responds to prospect behavior in real-time.

OpenClaw makes this possible for any GTM team—without the $50K/year enterprise platform price tag. Build your orchestration agent, define your logic, and let AI handle the complexity of timing, channel selection, and response handling.

Your prospects don't live in one channel. Your outreach shouldn't either.


Want multi-channel orchestration without building it yourself? MarketBetter's platform coordinates email, LinkedIn, phone, and more—with AI deciding the optimal next touch. Book a demo to see it in action.

Multi-Language Cold Outreach with AI: Expand Globally with Claude Code [2026]

· 10 min read
MarketBetter Team
Content Team, marketbetter.ai

Here's a paradox: B2B companies want to expand internationally, but their SDR teams only speak English.

The traditional solutions—hire native speakers, use translation agencies, or (worst) run English outreach in non-English markets—are either expensive, slow, or ineffective.

But AI has changed this. Claude Code can generate culturally-aware, professionally-translated outreach in 50+ languages—with the nuance that Google Translate will never achieve.

Let me show you how to build a multi-language outreach system that scales globally without scaling headcount.

Multi-language AI outreach diagram showing personalized emails in multiple languages

Why English-Only Outreach Fails Internationally

Let's look at the data:

  • 72% of consumers prefer buying from sites in their native language (CSA Research)
  • 56% say language is more important than price
  • Response rates drop 60-80% when using English in non-English markets

The math is brutal: your German prospects are 3-5x more likely to respond to German outreach.

But it's not just translation. It's localization:

LanguageCultural Nuance
GermanFormal titles matter. "Herr Doktor Müller" > "Hi Thomas"
FrenchRelationship-first. Don't pitch immediately.
JapaneseHierarchy is critical. Know their position.
SpanishRegional variations (Spain vs LATAM) are significant
ArabicRight-to-left text, formal greetings expected

AI doesn't just translate words. It adapts tone, formality, and cultural expectations.

The Multi-Language Outreach Framework

Here's how to build it:

  1. Language detection (identify prospect's language)
  2. Cultural context injection (regional norms, business etiquette)
  3. Native-quality generation (not translation—creation)
  4. Localized follow-ups (appropriate cadence for culture)

Step 1: Intelligent Language Detection

Before generating outreach, you need to know what language to use:

# Language detection and regional analysis
def detect_prospect_language(prospect):
"""
Determines appropriate outreach language based on multiple signals
"""

signals = {
'company_hq': prospect.get('company_country'),
'linkedin_language': prospect.get('linkedin_language_setting'),
'website_language': detect_website_language(prospect.get('company_website')),
'name_origin': analyze_name_origin(prospect.get('full_name')),
'email_domain': extract_country_from_domain(prospect.get('email'))
}

# Country to language mapping (with regional variants)
language_map = {
'Germany': 'de-DE',
'Austria': 'de-AT',
'Switzerland': 'de-CH', # Could also be French or Italian
'France': 'fr-FR',
'Canada': 'en-CA', # Or fr-CA if Quebec
'Mexico': 'es-MX',
'Spain': 'es-ES',
'Brazil': 'pt-BR',
'Japan': 'ja-JP',
# ... expanded mapping
}

# Weighted decision
primary_country = signals['company_hq'] or signals['linkedin_language']

# Special cases
if primary_country == 'Switzerland':
# Check region for language
return detect_swiss_language(prospect)

if primary_country == 'Canada':
# Check if Quebec
if prospect.get('province') == 'Quebec':
return 'fr-CA'
return 'en-CA'

return language_map.get(primary_country, 'en-US')

AI language detection workflow analyzing signals to determine prospect language

Step 2: Cultural Context Injection

This is where AI shines. Claude Code can incorporate cultural business norms:

# Cultural context for outreach generation
CULTURAL_CONTEXTS = {
'de-DE': {
'formality': 'high',
'greeting': 'Sehr geehrte/r {title} {last_name}',
'sign_off': 'Mit freundlichen Grüßen',
'tone': 'professional, direct, data-driven',
'avoid': ['humor in first touch', 'overly casual language', 'first name without permission'],
'include': ['company credentials', 'specific numbers', 'clear next steps'],
'timing': 'Avoid Friday afternoon, Germans leave early',
'title_importance': 'Always use Dr., Prof., etc. if applicable'
},
'fr-FR': {
'formality': 'high',
'greeting': 'Bonjour {title} {last_name}',
'sign_off': 'Cordialement',
'tone': 'elegant, relationship-focused, sophisticated',
'avoid': ['jumping to business immediately', 'aggressive follow-ups'],
'include': ['mutual connections', 'thoughtful opening', 'respect for their time'],
'timing': 'Never during August (vacances), lunch is sacred (12-14h)',
'title_importance': 'Use Monsieur/Madame always'
},
'ja-JP': {
'formality': 'very_high',
'greeting': '{last_name}様',
'sign_off': 'よろしくお願いいたします',
'tone': 'humble, respectful, group-oriented',
'avoid': ['direct criticism', 'rushing decisions', 'singling out individuals'],
'include': ['company introduction first', 'consensus-building language', 'long-term perspective'],
'timing': 'Respect hierarchy—contact appropriate level',
'title_importance': 'San (様) required, company name before person'
},
'es-MX': {
'formality': 'medium-high',
'greeting': 'Estimado/a {title} {last_name}',
'sign_off': 'Saludos cordiales',
'tone': 'warm, personal, relationship-oriented',
'avoid': ['rushing', 'cold/impersonal tone', 'ignoring small talk'],
'include': ['personal touch', 'reference to mutual benefit', 'flexibility in timing'],
'timing': 'Meetings often start late, be patient',
'title_importance': 'Licenciado/Ingeniero common for professionals'
},
'pt-BR': {
'formality': 'medium',
'greeting': 'Prezado/a \{first_name\}',
'sign_off': 'Atenciosamente',
'tone': 'friendly, enthusiastic, personal',
'avoid': ['being too formal', 'negative framing'],
'include': ['relationship building', 'optimism', 'personal connection'],
'timing': 'Carnaval and major holidays are dead periods',
'title_importance': 'First names common after initial contact'
}
}

def get_cultural_context(language_code):
return CULTURAL_CONTEXTS.get(language_code, CULTURAL_CONTEXTS['en-US'])

Step 3: Native-Quality Generation with Claude

This is the key insight: Claude doesn't translate. Claude creates.

When you ask Claude to write a cold email in German, it doesn't write in English and translate. It thinks in German business culture and generates natively.

# Native-language outreach generation with Claude Code
async def generate_localized_outreach(prospect, language_code):
"""
Generates culturally-appropriate outreach in target language
"""

cultural_context = get_cultural_context(language_code)

prompt = f"""
Generate a cold outreach email for a B2B SaaS product.

LANGUAGE: {language_code}

PROSPECT:
- Name: {prospect['name']}
- Title: {prospect['title']}
- Company: {prospect['company']}
- Industry: {prospect['industry']}

CULTURAL REQUIREMENTS:
- Formality level: {cultural_context['formality']}
- Greeting format: {cultural_context['greeting']}
- Sign-off: {cultural_context['sign_off']}
- Tone: {cultural_context['tone']}
- AVOID: {', '.join(cultural_context['avoid'])}
- INCLUDE: {', '.join(cultural_context['include'])}

PRODUCT VALUE PROP:
- Automates SDR workflows
- 70% reduction in manual research time
- 2x faster lead response

CONSTRAINTS:
- Write NATIVELY in {language_code}, do not translate from English
- Respect all cultural norms listed above
- Keep under 150 words
- Include ONE clear call to action
- Do not use English words unless they are standard industry terms

Generate the complete email including subject line.
"""

response = await claude.generate(
prompt=prompt,
model='claude-3-opus',
max_tokens=500
)

return {
'language': language_code,
'subject': extract_subject(response),
'body': extract_body(response),
'cultural_notes': cultural_context
}

Example output (German):

Betreff: Effizienzsteigerung im Vertrieb bei {Company}

Sehr geehrter Herr Dr. Müller,

als Leiter des Vertriebsteams bei {Company} kennen Sie die Herausforderung: Ihr Team verbringt mehr Zeit mit Recherche als mit Verkaufsgesprächen.

Unsere Kunden berichten von einer 70%igen Reduzierung des manuellen Aufwands bei der Lead-Qualifizierung. Für ein Unternehmen Ihrer Größe bedeutet das durchschnittlich 15 zusätzliche Stunden pro Woche für wertschöpfende Aktivitäten.

Wäre ein kurzes Gespräch nächste Woche möglich, um zu besprechen, wie dies auch bei {Company} funktionieren könnte?

Mit freundlichen Grüßen, [Name]

Notice: No "Hi Thomas!" No casual American tone. Professional German business communication.

Step 4: Localized Follow-Up Cadences

Different cultures have different expectations for follow-up:

# Culture-specific follow-up cadences
cadences:
de-DE:
name: "German Professional"
steps:
- day: 0
channel: email
note: "Initial outreach, formal"
- day: 5
channel: email
note: "Value-add follow-up with data/case study"
- day: 12
channel: linkedin
note: "Connection request with personalized note"
- day: 18
channel: email
note: "Final attempt, offer alternative contact"
notes: "Germans appreciate persistence but not pressure. Data > emotion."

fr-FR:
name: "French Relationship"
steps:
- day: 0
channel: email
note: "Thoughtful introduction, reference mutual connection if possible"
- day: 7
channel: linkedin
note: "Connect and engage with their content first"
- day: 14
channel: email
note: "Reference their recent work/news, suggest coffee"
- day: 21
channel: call
note: "If engaged, phone call (never cold)"
notes: "Relationship first. Never rush. August is dead."

ja-JP:
name: "Japanese Formal"
steps:
- day: 0
channel: email
note: "Formal introduction of company and purpose"
- day: 10
channel: email
note: "Follow-up with additional company credentials"
- day: 21
channel: introduction
note: "Seek warm introduction through mutual contact"
- day: 35
channel: email
note: "Gentle follow-up, offer to meet at their convenience"
notes: "Patience is essential. Group decision-making takes time. Warm intros > cold."

Automating with OpenClaw

Here's how to tie it all together with continuous multi-language campaigns:

# Multi-language outreach automation with OpenClaw
schedule:
kind: cron
expr: "0 8 * * *" # Daily at 8am

payload:
kind: agentTurn
message: |
Process today's international outreach queue:

1. LANGUAGE DETECTION
For each new prospect without assigned language:
- Detect appropriate language
- Assign cultural context
- Log decision reasoning

2. CONTENT GENERATION
For prospects needing outreach:
- Generate native-language email using cultural context
- Ensure compliance with regional requirements (GDPR for EU, etc.)
- Queue for review if confidence < 90%

3. TIMING OPTIMIZATION
Adjust send times for recipient timezone:
- DE/FR/EU: 9-10am local
- JP: 10-11am local
- LATAM: 10-11am local
- Respect cultural no-send times (Friday PM for DE, August for FR)

4. FOLLOW-UP MANAGEMENT
Check prospects in active sequences:
- Advance to next step if appropriate
- Adjust based on engagement signals
- Flag any responses for native review

Report: Languages processed, emails generated, cultural flags raised

Quality Assurance: When to Get Human Review

AI-generated foreign language outreach is good—but not perfect. Build in review for:

High-stakes situations:

  • Enterprise deals (> $100K potential)
  • Sensitive industries (government, healthcare)
  • Cultures with high formality requirements (Japan, Korea)

Low-confidence scenarios:

  • Mixed signals on language preference
  • Unusual name origins
  • Multi-national companies (HQ vs local office)
# Quality assurance routing
def route_for_review(outreach, prospect):
"""
Determines if AI-generated outreach needs human review
"""

needs_review = False
reasons = []

# High-value deals
if prospect['estimated_acv'] > 100000:
needs_review = True
reasons.append('High ACV - enterprise touch required')

# High-formality cultures
if outreach['language'] in ['ja-JP', 'ko-KR', 'zh-CN']:
needs_review = True
reasons.append('High-formality culture - native review recommended')

# Low confidence detection
if outreach['language_confidence'] < 0.85:
needs_review = True
reasons.append(f"Language detection confidence: {outreach['language_confidence']}")

# First outreach in new language
if not has_previous_success(outreach['language']):
needs_review = True
reasons.append('First campaign in this language - establish baseline')

return {
'needs_review': needs_review,
'reasons': reasons,
'reviewer_type': 'native_speaker' if needs_review else None
}

Measuring Success Across Languages

Track these metrics by language:

MetricWhy It Matters
Open rate by languageValidates subject line localization
Reply rate by languageCore effectiveness measure
Positive reply rateQuality of localization
Meeting booked rateEnd conversion
Time to responseCultural timing alignment

Expected benchmarks:

RegionOpen RateReply RatePositive Reply
DACH (DE/AT/CH)35-45%8-12%4-6%
France30-40%6-10%3-5%
LATAM40-50%10-15%5-8%
Japan25-35%3-6%1-3%
Nordics35-45%8-12%4-6%

Lower absolute numbers in Japan are normal—decision cycles are longer but deal sizes often larger.

Implementation Roadmap

Week 1: Market Selection

  • Identify top 3-5 target markets beyond English
  • Research cultural business norms for each
  • Document language-specific requirements

Week 2: Detection & Context

  • Build language detection pipeline
  • Create cultural context files for each market
  • Test detection accuracy on existing prospects

Week 3: Generation & Testing

  • Configure Claude prompts for each language
  • Generate sample outreach, get native review
  • Refine based on feedback

Week 4: Launch & Measure

  • Deploy multi-language campaigns
  • Track metrics by language
  • Iterate on underperforming regions
Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

The Global Opportunity

Most B2B companies leave international markets to competitors because "we don't have German speakers."

That's no longer an excuse.

With Claude Code generating native-quality outreach and OpenClaw automating the workflow, your 5-person SDR team can cover markets that used to require 50.

The companies expanding fastest aren't the ones with the biggest teams. They're the ones with the smartest systems.

Build yours.


Want to see how MarketBetter helps teams scale personalized outreach globally?

Book a Demo →

OpenAI Codex CLI for Sales: 8 GTM Workflows That Cut Manual Work to Zero [2026]

· 9 min read
MarketBetter Team
Content Team, marketbetter.ai

OpenAI released GPT-5.3-Codex on February 5, 2026—their most capable agentic coding model yet. The Codex CLI puts this power at your fingertips, letting you automate GTM tasks directly from your terminal.

This guide covers everything GTM teams need to know: installation, essential commands, and real workflows for sales automation, content generation, and pipeline management. For ready-to-run prompts, pair it with our 30 best Codex prompts for sales and GTM.

OpenAI Codex CLI interface showing terminal commands for GTM automation

What's New in GPT-5.3 Codex

Before diving into the CLI, here's why GPT-5.3 matters:

FeatureGPT-5.2 CodexGPT-5.3 Codex
SpeedBaseline25% faster
Mid-turn steeringLimitedFull support
Multi-file context50K tokens100K tokens
Tool reliability89%96%
Reasoning depthGoodSignificantly improved

The killer feature? Mid-turn steering—you can direct Codex while it's working, correcting course without starting over.

Installing the Codex CLI

Get started in 60 seconds:

# Install globally via npm
npm install -g @openai/codex

# Verify installation
codex --version
# codex 1.4.0 (gpt-5.3-codex)

# Authenticate
codex auth login
# Opens browser for OpenAI authentication

First Run

Test your installation:

codex "explain what you can do for a sales team"

You should see Codex describe its capabilities for sales automation, data analysis, and content generation.

Essential Codex Commands for GTM

Basic Syntax

codex "<natural language task>"

Codex interprets your request and executes the appropriate actions. You can also:

# Run in a specific directory
codex --cwd /path/to/project "<task>"

# Include files for context
codex --include "*.csv" "<task>"

# Set output format
codex --output json "<task>"

# Enable mid-turn steering
codex --interactive "<task>"

The --interactive Flag (Mid-Turn Steering)

This is GPT-5.3's superpower. Instead of waiting for Codex to finish, you can course-correct in real-time:

codex --interactive "analyze our pipeline and suggest improvements"

While Codex works, you can type commands like:

  • focus on deals stuck longer than 30 days
  • ignore deals under $10K
  • also check for missing next steps

Codex adjusts its analysis mid-stream without starting over.

Mid-turn steering diagram showing real-time feedback while AI is working

GTM Workflows with Codex CLI

1. Pipeline Analysis

Analyze your CRM data directly:

# Export pipeline from your CRM first (or connect via API)
codex --include "pipeline.csv" "
Analyze this sales pipeline and identify:
1. Deals that have been stuck in the same stage for >30 days
2. Deals with no recent activity
3. Deals missing next steps
4. Predicted close rates by stage

Output as a prioritized action list for the sales manager.
"

Sample output:

## Pipeline Health Report

### 🚨 Stuck Deals (30+ days same stage)
1. Acme Corp - Proposal stage for 47 days - $85K
→ Action: Escalate to VP Sales, consider discount strategy
2. TechStart Inc - Demo stage for 38 days - $32K
→ Action: Re-engage champion, check for competing eval

### ⚠️ Missing Next Steps (23 deals)
- Priority 1: Deals >$50K with no activity last 14 days
- Recommend: Mandatory next-step field in CRM

### 📊 Stage Conversion Rates
- Lead → Discovery: 42% (healthy)
- Discovery → Demo: 68% (above benchmark)
- Demo → Proposal: 31% (⚠️ below benchmark 45%)
- Proposal → Closed Won: 28% (needs attention)

2. Lead Research at Scale

Research a list of leads:

codex --include "leads.csv" --output json "
For each company in this list:
1. Find their LinkedIn company page
2. Get employee count and recent funding
3. Identify likely decision makers in Sales/Marketing
4. Note any recent news or hiring signals

Output as enriched JSON with research_notes for each lead.
"

3. Email Sequence Generation

Generate personalized email sequences:

codex "
Create a 5-email sequence for SDR outreach to VP of Sales at mid-market SaaS companies.

Context: We're MarketBetter, an AI-powered SDR platform.
Pain point: SDR productivity and lead prioritization
Differentiator: We tell SDRs WHO to contact AND WHAT to do

Requirements:
- Email 1: Cold intro, <100 words
- Email 2: Value-add (share relevant content)
- Email 3: Social proof (customer results)
- Email 4: Direct ask for meeting
- Email 5: Breakup email

Include subject lines and personalization tokens.
"

4. Competitor Analysis

Research competitors systematically:

codex --interactive "
Research these competitors and create a comparison matrix:
- Warmly
- 6sense
- Apollo
- ZoomInfo

For each, find:
1. Pricing (actual prices, not just 'contact us')
2. Key features
3. G2 rating and top complaints
4. Recent product updates
5. Where MarketBetter wins

I'll guide you as you research.
"

With --interactive, you can steer:

  • "Dig deeper on Warmly's pricing—check G2 reviews for price mentions"
  • "Skip ZoomInfo, we have that already"
  • "Focus more on their visitor identification capabilities"

5. Meeting Prep

Prepare for sales calls:

codex "
I have a demo call with Sarah Chen, VP Sales at DataFlow Inc.

Research:
1. Sarah's LinkedIn background
2. DataFlow Inc recent news/funding
3. Their current tech stack (from job postings)
4. Common challenges for companies their size
5. 3 personalized talking points

Also draft 3 discovery questions specific to their situation.
"

6. Content Generation

Generate blog post outlines:

codex "
Create an outline for a blog post: 'Why Intent Data Fails Without Action'

Target keyword: intent data for sales
Word count: 2000 words
Audience: VP Sales, SDR Managers

Include:
- Compelling intro hook
- 5-7 main sections with subheadings
- Data points to research
- CTA to MarketBetter demo

Make it contrarian—most content says intent data is magic.
We say it's useless without the action layer.
"

7. CRM Data Cleanup

Fix messy CRM data:

codex --include "contacts.csv" "
Clean this contact list:
1. Standardize company names (remove Inc., LLC variants)
2. Fix obvious email typos (@gmial.com, etc.)
3. Parse full names into first/last
4. Flag likely duplicates
5. Validate phone number formats

Output as cleaned CSV with a 'changes_made' column.
"

Advanced Codex Patterns

Chaining Commands

Build complex workflows:

# Research → Enrich → Generate sequence
codex "research DataFlow Inc" > /tmp/research.txt && \
codex --include /tmp/research.txt "generate 3 personalized email openers based on this research"

Template-Based Generation

Create reusable prompt templates:

# Save as ~/.codex/templates/competitor-analysis.txt
cat << 'EOF' > ~/.codex/templates/competitor-analysis.txt
Research {{COMPETITOR}} and provide:
1. Company overview (employees, funding, HQ)
2. Product positioning
3. Pricing structure
4. Key differentiators
5. Customer complaints (from G2/Capterra)
6. How we beat them

Format as markdown with clear sections.
EOF

# Use the template
codex --template competitor-analysis COMPETITOR=Warmly

Integration with Other Tools

Combine Codex with your existing stack:

# Pull from HubSpot, analyze with Codex, push back
hubspot contacts list --limit 100 --format csv > leads.csv
codex --include leads.csv "score these leads 1-100 based on fit for AI SDR tools"
# Parse output and update HubSpot via API

Codex CLI vs Claude Code vs ChatGPT

When to use each:

TaskBest ToolWhy
Multi-file code changesCodex CLIPurpose-built for code
Long document analysisClaude Code200K context window
Quick questionsChatGPTFastest for simple tasks
Pipeline data analysisCodex CLIStructured output
Email writingClaude CodeBetter nuance
Competitor researchEitherBoth strong
Meeting prepCodex (interactive)Mid-turn steering

The real answer? Use them together. Codex for structured tasks and code, Claude for nuanced writing and analysis.

Cost Considerations

Codex CLI usage is charged per token:

UsageApproximate Cost
Simple task (&lt;1K tokens)~$0.02
Pipeline analysis (5K tokens)~$0.10
Research task (10K tokens)~$0.20
Large batch (50K tokens)~$1.00

For most GTM teams, budget $50-100/month for heavy CLI usage. Compare that to the hours saved.

Common Gotchas

1. Rate Limits

Free tier: 20 requests/minute. Paid: 100 requests/minute.

For batch processing:

# Add delays between requests
for company in $(cat companies.txt); do
codex "research $company"
sleep 3
done

2. Context Limits

Even with 100K tokens, large files need chunking:

# Process large CSV in chunks
split -l 100 huge_leads.csv chunk_
for chunk in chunk_*; do
codex --include $chunk "process this batch"
done

3. Output Consistency

For structured output, be explicit:

# Bad: "analyze this data"
# Good:
codex "analyze this data and return JSON with fields:
{insights: string[], recommendations: string[], priority: high|medium|low}"

The MarketBetter Integration

MarketBetter uses the same AI models under the hood—but packages them into a complete GTM platform:

  • Daily Playbook — Codex-style analysis of your entire pipeline, delivered as actionable tasks
  • AI Chatbot — GPT-5.3 powers real-time lead qualification
  • Smart Dialer — AI-prioritized call lists based on intent signals
  • Email Automation — Personalized sequences generated at scale

The difference? MarketBetter eliminates the prompting and integration work. Your SDRs get AI-powered insights without touching a command line.

See how MarketBetter turns AI into pipeline →

Quick Reference Card

# Installation
npm install -g @openai/codex
codex auth login

# Basic usage
codex "<task>"

# With file context
codex --include "data.csv" "<task>"

# Interactive mode (mid-turn steering)
codex --interactive "<task>"

# JSON output
codex --output json "<task>"

# Specific directory
codex --cwd /path/to/project "<task>"

# Help
codex --help
Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

Getting Started Checklist

  • Install Codex CLI (npm install -g @openai/codex)
  • Authenticate (codex auth login)
  • Test basic command
  • Try --interactive mode
  • Export CRM data for analysis
  • Create first prompt template
  • Set up shell alias for common tasks
  • Budget token usage

The Codex CLI puts GPT-5.3's power directly in your terminal. For GTM teams, that means faster research, smarter analysis, and more personalized outreach—all from the command line.


Want more AI automation for GTM? Check out Codex vs Claude Code for sales automation and building AI agents with OpenClaw.

OpenAI Codex for Demo Personalization: Win More Deals with Tailored Demos [2026]

· 11 min read
MarketBetter Team
Content Team, marketbetter.ai

Here's a brutal truth about B2B demos: 68% of prospects say demos are too generic. They sit through 45 minutes of features they don't care about, waiting for the one capability that actually solves their problem. Most never make it to that point—they've already mentally checked out.

The companies winning in 2026 don't run generic demos. They run shows that feel custom-built for each prospect. And with OpenAI's GPT-5.3 Codex (released February 5, 2026), building that personalization engine is now accessible to any GTM team.

AI Demo Personalization System

This guide shows you how to use Codex's agentic capabilities to automatically generate personalized demo scripts, custom slide decks, and industry-specific talking points—all from your CRM data and meeting notes.

Why Generic Demos Lose Deals

The data is clear:

  • 68% of buyers say demos don't address their specific needs
  • 52% of prospects decide within the first 5 minutes if they'll buy
  • 44% of buyers abandon vendors who can't explain relevance to their business
  • Personalized demos have a 45% higher close rate than generic ones

Generic vs Personalized Demo Comparison

The problem isn't that AEs don't want to personalize—it's that personalization takes time they don't have. Research the company, customize the slides, reorder features for relevance, find the right case study, rehearse the new flow... that's 1-2 hours of prep per demo.

Most reps are running 3-5 demos per day. The math doesn't work.

What Makes a Demo Feel Personalized?

Before automating, let's break down what "personalized" actually means:

1. Relevant Opening

Don't start with your product. Start with their world:

  • Recent company news or announcements
  • Industry-specific challenges
  • Reference to their stated pain points

2. Reordered Feature Sequence

Show them what they care about first:

  • Lead with the capability they asked about
  • Skip or minimize features irrelevant to their use case
  • Save "nice-to-haves" for Q&A

3. Industry-Specific Language

Speak their language:

  • Use their industry's terminology
  • Reference their competitive landscape
  • Cite metrics that matter in their world

4. Relevant Social Proof

Show them peers, not just logos:

  • Case studies from similar company size
  • Same industry or use case
  • Metrics that map to their goals

5. Custom Demo Environment

When possible, show their reality:

  • Their company name in the demo
  • Realistic sample data for their industry
  • Workflows that match their process

GPT-5.3 Codex: Built for Agentic Personalization

OpenAI's Codex (released February 5, 2026) is specifically designed for agentic tasks like demo personalization. Key capabilities:

  • Mid-turn steering — Direct the agent while it works, perfect for iterative customization
  • 25% faster — Get personalization outputs in seconds, not minutes
  • Multi-file context — Understands your entire demo deck + CRM data simultaneously
  • Code + content — Can generate both slides content AND automation scripts

Here's the architecture for an automated demo personalization system:

Building the Demo Personalization Engine

Step 1: Gather Prospect Intelligence

First, compile everything you know about the prospect:

async function gatherDemoContext(dealId) {
// CRM data
const deal = await crm.getDeal(dealId);
const company = await crm.getCompany(deal.companyId);
const contacts = await crm.getContacts(deal.contactIds);

// Meeting history
const meetings = await crm.getMeetings(dealId);
const discoveryNotes = meetings
.filter(m => m.type === 'discovery')
.map(m => m.notes)
.join('\n');

// Enrich with external data
const companyNews = await newsApi.search({
company: company.name,
daysBack: 30
});

const industryTrends = await getIndustryInsights(company.industry);

// Find relevant case studies
const relevantCaseStudies = await caseStudyDb.find({
industry: company.industry,
size: company.employeeRange,
useCase: deal.primaryUseCase
});

// Get competitor intel
const competitorMentions = extractCompetitors(discoveryNotes);
const competitorIntel = await getCompetitorBattlecards(competitorMentions);

return {
company,
contacts,
deal,
discoveryNotes,
companyNews,
industryTrends,
caseStudies: relevantCaseStudies,
competitors: competitorIntel
};
}

Step 2: Generate the Demo Script with Codex

Use GPT-5.3 Codex to generate a personalized demo flow:

const { OpenAI } = require('openai');
const codex = new OpenAI({ model: 'gpt-5.3-codex' });

async function generateDemoScript(context) {
const response = await codex.chat.completions.create({
model: 'gpt-5.3-codex',
messages: [
{
role: 'system',
content: `You are an expert sales demo strategist. Generate a
personalized demo script that will resonate with this specific prospect.

DEMO STRUCTURE:
1. Personalized Opening (2 min) - Reference their world
2. Pain Validation (3 min) - Confirm what you heard in discovery
3. Priority Feature #1 (10 min) - What they care most about
4. Priority Feature #2 (8 min) - Second most relevant
5. Integration/Workflow (5 min) - How it fits their stack
6. Social Proof (3 min) - Case study from similar company
7. Pricing Context (2 min) - Frame value, not cost
8. Next Steps (2 min) - Clear path forward

OUTPUT FORMAT:
- Include speaker notes for each section
- Add talk tracks for common objections
- Include specific data points to mention
- Flag areas needing live customization`
},
{
role: 'user',
content: `Create a demo script for this opportunity:

COMPANY: ${context.company.name}
INDUSTRY: ${context.company.industry}
SIZE: ${context.company.employeeCount} employees
REVENUE: $${context.company.revenue}M

DISCOVERY INSIGHTS:
${context.discoveryNotes}

KEY PAIN POINTS IDENTIFIED:
${extractPainPoints(context.discoveryNotes).join('\n- ')}

RECENT COMPANY NEWS:
${context.companyNews.map(n => `- ${n.headline}`).join('\n')}

RELEVANT CASE STUDY:
${JSON.stringify(context.caseStudies[0])}

COMPETITORS MENTIONED:
${context.competitors.map(c => c.name).join(', ')}

Generate a complete, personalized demo script.`
}
],
max_tokens: 4000,
response_format: { type: 'json_object' }
});

return JSON.parse(response.choices[0].message.content);
}

Step 3: Customize the Slide Deck

Codex can also modify your master deck for each prospect:

async function customizeSlideDeck(masterDeck, context, demoScript) {
// Parse the master deck (Google Slides, PowerPoint, etc.)
const slides = await parseDeck(masterDeck);

const customizations = await codex.chat.completions.create({
model: 'gpt-5.3-codex',
messages: [
{
role: 'system',
content: `You are customizing a sales demo deck. For each slide,
determine what changes are needed for this specific prospect.

Types of customizations:
1. TEXT_REPLACE - Swap placeholder text
2. REORDER - Move slide to different position
3. SKIP - Mark slide to hide
4. ADD_DATA - Insert prospect-specific data
5. CASE_STUDY_SWAP - Replace case study content`
},
{
role: 'user',
content: `MASTER DECK SLIDES:
${slides.map((s, i) => `[${i}] ${s.title}: ${s.content.substring(0, 200)}`).join('\n')}

PROSPECT CONTEXT:
Company: ${context.company.name}
Industry: ${context.company.industry}
Pain Points: ${extractPainPoints(context.discoveryNotes).join(', ')}

DEMO SCRIPT FLOW:
${demoScript.sections.map(s => s.title).join(' → ')}

RELEVANT CASE STUDY:
${JSON.stringify(context.caseStudies[0])}

Output a JSON array of customization instructions.`
}
]
});

// Apply customizations
const customizedDeck = applyCustomizations(slides, customizations);

return customizedDeck;
}

Step 4: Generate Talking Points and Objection Handlers

Pre-arm your AE with responses to likely objections:

async function generateObjectionHandlers(context) {
const handlers = await codex.chat.completions.create({
model: 'gpt-5.3-codex',
messages: [
{
role: 'system',
content: `Generate objection handling scripts specific to this
prospect's context. Include:
- The likely objection based on their situation
- Why they might raise it
- Data-backed response
- Reframe to positive

Be specific, not generic.`
},
{
role: 'user',
content: `PROSPECT CONTEXT:
Industry: ${context.company.industry}
Company Size: ${context.company.employeeCount}
Current Tools: ${context.deal.currentSolution}
Budget Range: ${context.deal.budget}
Competitors Evaluating: ${context.competitors.map(c => c.name).join(', ')}

DISCOVERY CONCERNS:
${extractConcerns(context.discoveryNotes).join('\n')}

Generate 5 likely objections with tailored responses.`
}
]
});

return handlers.choices[0].message.content;
}

Real-World Example: Manufacturing Company Demo

Input:

  • Company: Precision Parts Inc. (450 employees, manufacturing)
  • Pain Points: "Reps don't know which accounts to prioritize" + "No visibility into what competitors are doing"
  • Current Tools: Salesforce + spreadsheets
  • Competitor Evaluating: ZoomInfo

Generated Demo Script (excerpt):

{
"opening": {
"duration": "2 minutes",
"personalizedHook": "I saw Precision Parts just announced the expansion into aerospace components last month—congratulations. That kind of move into a new vertical is exactly where prioritization becomes critical. You mentioned your reps don't know which accounts to focus on—let me show you how that changes today.",
"speakerNotes": "Reference their Jan 15 press release. Don't dwell—use as credibility builder that you did your homework."
},

"painValidation": {
"duration": "3 minutes",
"talkTrack": "In our discovery call, you mentioned two things that stuck with me: first, your 8-person sales team is essentially flying blind on account prioritization. Second, you're concerned about what competitors are doing in the aerospace space. Did I capture that right?",
"transition": "Let me show you how we solve both of those—starting with prioritization since you said that's the bigger fire right now."
},

"featurePriority1": {
"feature": "Account Prioritization & ICP Scoring",
"duration": "10 minutes",
"customization": "Show manufacturing-specific signals: plant expansions, equipment purchases, regulatory filings",
"industryLanguage": "Use terms: 'tier-1 supplier', 'OEM relationships', 'MRO contracts'",
"relevantMetric": "Manufacturing companies see 34% faster deal cycles with intent-based prioritization"
},

"featurePriority2": {
"feature": "Competitive Intelligence Dashboard",
"duration": "8 minutes",
"customization": "Pre-load demo environment with aerospace competitors they mentioned",
"differentiator": "Unlike ZoomInfo (which they're evaluating), show real-time monitoring vs static database"
},

"socialProof": {
"caseStudy": "Allied Manufacturing",
"relevance": "Same size (500 emp), same industry, same Salesforce integration",
"metric": "2.3x increase in qualified pipeline within 90 days",
"quote": "'Finally, my team knows where to focus without me micromanaging.'"
},

"objectionPrep": [
{
"objection": "ZoomInfo has more data",
"context": "They mentioned evaluating ZoomInfo",
"response": "ZoomInfo has great contact data—we actually integrate with them. The difference is what you DO with that data. ZoomInfo tells you WHO exists. We tell you WHO to call and WHAT to say. For manufacturers entering new verticals like aerospace, it's the prioritization layer that moves the needle.",
"proof": "Allied Manufacturing uses both. They said ZoomInfo fills the top of funnel, we tell them where to focus."
}
]
}

Personalized Demo Impact Statistics

Mid-Turn Steering: Codex's Killer Feature

What makes GPT-5.3 Codex special for demo personalization is mid-turn steering. You can direct the agent while it's generating:

// Start generation
const stream = codex.chat.completions.create({
model: 'gpt-5.3-codex',
messages: [...],
stream: true
});

// Monitor and steer mid-generation
for await (const chunk of stream) {
const partialOutput = chunk.choices[0].delta.content;

// If going off-track, inject steering
if (partialOutput.includes('generic feature list')) {
await stream.steer({
instruction: 'Focus on manufacturing-specific capabilities only'
});
}
}

This means you can build interactive personalization tools where AEs can guide the AI in real-time—combining human judgment with AI speed.

Integration with Demo Workflow

Pre-Demo Automation

// Trigger 2 hours before scheduled demo
cron.schedule('0 */1 * * *', async () => {
const upcomingDemos = await calendar.getDemos({
timeWindow: '2-3 hours from now'
});

for (const demo of upcomingDemos) {
const context = await gatherDemoContext(demo.dealId);
const script = await generateDemoScript(context);
const deck = await customizeSlideDeck(MASTER_DECK, context, script);
const handlers = await generateObjectionHandlers(context);

// Send prep package to AE
await slack.sendDM(demo.ownerId, {
text: `🎯 Demo prep ready for ${context.company.name} in 2 hours`,
attachments: [
{ title: 'Personalized Script', content: script },
{ title: 'Custom Deck', url: deck.url },
{ title: 'Objection Handlers', content: handlers }
]
});
}
});

Post-Demo Follow-Up Generation

// After demo ends, generate follow-up
async function postDemoAutomation(demoId, demoNotes) {
const context = await gatherDemoContext(demoId);

// Generate personalized follow-up based on what happened
const followUp = await codex.chat.completions.create({
model: 'gpt-5.3-codex',
messages: [{
role: 'user',
content: `Based on this demo, generate follow-up:

DEMO NOTES:
${demoNotes}

ORIGINAL CONTEXT:
${JSON.stringify(context)}

Generate:
1. Follow-up email addressing specific questions raised
2. Relevant resources to send
3. Suggested next step with timeline`
}]
});

return followUp;
}

Measuring Personalization ROI

Track these metrics to prove the value:

MetricGeneric DemosPersonalized DemosLift
Demo-to-Opportunity35%52%+49%
Opportunity-to-Close22%31%+41%
Average Deal Size$32K$41K+28%
Sales Cycle Length47 days34 days-28%
NPS (Demo Experience)3467+97%

The math: If personalization increases your demo-to-close rate by 20% and you run 50 demos/month at $40K ACV, that's an additional $400K in ARR annually.

Getting Started with MarketBetter

Building demo personalization is powerful, but it's just one piece of the puzzle. MarketBetter provides the complete AI-powered sales enablement stack:

  • Automated demo prep — Personalized scripts and decks generated before every call
  • Real-time battle cards — Competitor intel surfaced when you need it
  • CRM integration — Pulls from HubSpot/Salesforce, no manual context gathering
  • Meeting analysis — Learns from every demo to improve recommendations

The goal isn't to replace AEs—it's to give them superpowers. Let AI handle the personalization heavy-lifting so your team can focus on building relationships and closing deals.

Book a Demo →

Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

Key Takeaways

  1. Generic demos lose deals — 68% of buyers say demos don't address their needs
  2. Personalization takes time — 1-2 hours per demo prep doesn't scale
  3. GPT-5.3 Codex enables automation — Generate scripts, customize decks, prepare objection handlers
  4. Mid-turn steering is the differentiator — Real-time direction gives you control over AI output
  5. ROI is measurable — 20% close rate improvement = significant revenue impact

Your demo is often the make-or-break moment in the sales cycle. Make sure every prospect feels like you built the whole product just for them. With Codex, you practically did.

OpenClaw Setup Guide for GTM Teams: From Zero to AI SDR [2026]

· 8 min read
MarketBetter Team
Content Team, marketbetter.ai

You've heard OpenClaw can turn AI into your always-on sales assistant. You're intrigued by the $0 price tag versus $40K enterprise alternatives.

But you're staring at a GitHub page wondering: "How do I actually make this work for my sales team?"

This guide takes you from zero to a working AI SDR in under an hour. No engineering degree required. If you can copy-paste commands and edit a text file, you can do this.

OpenClaw Architecture for GTM

What You'll Build

By the end of this guide, you'll have:

✅ OpenClaw running on your machine (or a cloud server) ✅ AI assistant connected to WhatsApp or Slack ✅ Basic CRM integration with HubSpot ✅ Web search capability for prospect research ✅ Your first automated workflow (daily pipeline summary)

Total time: 45-60 minutes.

Prerequisites

You need:

  • A computer (Mac, Windows, or Linux)
  • An Anthropic API key (get one at console.anthropic.com)
  • A WhatsApp account OR Slack workspace
  • (Optional) HubSpot account for CRM integration

You don't need:

  • Programming experience
  • DevOps knowledge
  • A computer science degree

Part 1: Installing OpenClaw (15 minutes)

Step 1: Install Node.js

OpenClaw runs on Node.js. Install it first:

Mac:

brew install node

Windows: Download from nodejs.org and run the installer.

Linux (Ubuntu/Debian):

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs

Verify it worked:

node --version
# Should show v22.x.x or similar

Step 2: Install OpenClaw

One command:

npx openclaw@latest init

This downloads OpenClaw and runs the setup wizard.

The wizard asks:

  1. API Key: Paste your Anthropic API key
  2. Model: Select Claude Sonnet 4 (best balance of speed and capability)
  3. Channels: Select WhatsApp or Slack (we'll configure in Part 2)

When it finishes, you'll see:

✅ OpenClaw initialized!
Run 'openclaw gateway start' to begin.

Step 3: Start the Gateway

openclaw gateway start

OpenClaw is now running. You'll see:

🚀 Gateway started
📡 Listening for connections...

Leave this terminal open. OpenClaw runs here.

Part 2: Connecting a Messaging Channel (10 minutes)

Your AI needs a way to communicate. Let's connect WhatsApp (easiest) or Slack.

Option A: WhatsApp (Personal or Business)

In a new terminal:

openclaw whatsapp link

A QR code appears. Scan it with WhatsApp on your phone (Settings → Linked Devices → Link a Device).

Once linked:

✅ WhatsApp connected!
Send any message to your own number to test.

Test it: Send "Hello" to yourself on WhatsApp. Your AI should respond!

Option B: Slack

  1. Create a Slack App at api.slack.com/apps
  2. Add these Bot Token Scopes:
    • chat:write
    • channels:history
    • channels:read
    • app_mentions:read
  3. Install the app to your workspace
  4. Copy the Bot Token

Add to your OpenClaw config (~/.openclaw/config.yaml):

channels:
slack:
token: "xoxb-your-bot-token"
appToken: "xapp-your-app-token" # For Socket Mode

Restart OpenClaw:

openclaw gateway restart

Test it: Mention your bot in Slack. It should respond!

Part 3: Configuring Your AI Persona (10 minutes)

Your AI shouldn't sound like a generic chatbot. Let's give it personality.

Creating Your Sales Assistant Persona

Open ~/.openclaw/workspace/SOUL.md and customize:

# SOUL.md - Your Sales AI

You are a sales assistant for [Your Company].

## Your Role
- Help SDRs research prospects
- Draft personalized outreach
- Monitor pipeline and alert on important changes
- Answer questions about our product and competitors

## Your Tone
- Professional but not stiff
- Concise—you value people's time
- Confident—you know the product well
- Helpful—you anticipate what's needed

## What You Know
- Our product: [Brief description]
- Our ICP: [Who we sell to]
- Our competitors: [Main competitors]
- Our differentiators: [What makes us unique]

## Rules
- Never make up information about prospects
- Always cite sources when researching
- Ask clarifying questions if a request is ambiguous
- Protect customer data—never share externally

Save the file. OpenClaw reads this automatically.

Testing the Persona

Message your AI:

"What can you help me with?"

It should respond based on your SOUL.md configuration.

Part 4: Adding Web Research (5 minutes)

For your AI to research prospects, it needs web access.

  1. Get a free API key at brave.com/search/api/
  2. Add to your environment:
# Add to ~/.bashrc or ~/.zshrc
export BRAVE_API_KEY="your-brave-api-key"
  1. Restart OpenClaw:
openclaw gateway restart

Test It

Message your AI:

"Research Acme Corp for me—what do they do and any recent news?"

It should search the web and return a summary.

OpenClaw Terminal Commands

Part 5: HubSpot Integration (10 minutes)

Now let's connect your CRM so your AI can access real prospect data.

Getting HubSpot API Access

  1. Go to HubSpot → Settings → Integrations → Private Apps
  2. Create a new private app
  3. Grant these scopes:
    • crm.objects.contacts.read
    • crm.objects.contacts.write
    • crm.objects.companies.read
    • crm.objects.deals.read
  4. Copy the access token

Configure OpenClaw

Add to your environment:

export HUBSPOT_ACCESS_TOKEN="your-token"

Create a HubSpot integration script (~/.openclaw/workspace/scripts/hubspot.js):

const hubspot = require('@hubspot/api-client');

const client = new hubspot.Client({
accessToken: process.env.HUBSPOT_ACCESS_TOKEN
});

// Search contacts
async function searchContacts(query) {
const response = await client.crm.contacts.searchApi.doSearch({
query: query,
limit: 10,
properties: ['firstname', 'lastname', 'email', 'company']
});
return response.results;
}

// Get deal pipeline
async function getDeals() {
const response = await client.crm.deals.basicApi.getPage(100, undefined, [
'dealname', 'amount', 'dealstage', 'closedate'
]);
return response.results;
}

module.exports = { searchContacts, getDeals };

Install the HubSpot SDK:

cd ~/.openclaw/workspace
npm install @hubspot/api-client

Test It

Message your AI:

"Look up John Smith in our CRM"

It should search HubSpot and return matching contacts.

Part 6: Your First Automation (10 minutes)

Let's set up a daily pipeline summary that runs automatically.

Create the Cron Job

OpenClaw uses cron jobs for scheduled tasks. Add to your config:

# ~/.openclaw/config.yaml
cron:
- name: "Daily Pipeline Summary"
schedule:
kind: cron
expr: "0 9 * * *" # 9 AM daily
tz: "America/Chicago" # Your timezone
payload:
kind: systemEvent
text: |
Generate a morning pipeline briefing:
1. Check HubSpot for deals closing this week
2. List any deals that haven't been updated in 7+ days
3. Highlight the top 3 deals by value
4. Send summary to the sales channel
sessionTarget: main

Restart to Apply

openclaw gateway restart

Tomorrow at 9 AM, your AI will automatically generate and send a pipeline summary.

Test It Now

Don't want to wait? Trigger manually:

openclaw cron run "Daily Pipeline Summary"

Part 7: Common GTM Workflows

Here are ready-to-use workflows for sales teams:

Prospect Research on Demand

When someone messages:

"Research [Company Name]"

Your AI will:

  1. Search the web for company information
  2. Find recent news
  3. Check for relevant job postings
  4. Summarize findings

Pre-Call Briefing

When someone messages:

"Prep me for my call with [Name] at [Company]"

Your AI will:

  1. Research the person and company
  2. Check your CRM for history
  3. Generate talking points
  4. Suggest opening questions

Email Draft

When someone messages:

"Draft an email to [Name] at [Company] about [topic]"

Your AI will:

  1. Research the prospect
  2. Draft a personalized email
  3. Suggest subject lines
  4. Format for copy-paste

Deal Alert

Set up an alert for stale deals:

cron:
- name: "Stale Deal Alert"
schedule:
kind: cron
expr: "0 10 * * 1-5" # 10 AM weekdays
payload:
kind: systemEvent
text: |
Check HubSpot for deals not updated in 7+ days.
For each stale deal, send an alert with:
- Deal name and value
- Days since last activity
- Suggested next action
sessionTarget: main

Troubleshooting Common Issues

"Command not found: openclaw"

Make sure Node.js is in your PATH:

export PATH=$PATH:$(npm bin -g)

WhatsApp QR Code Won't Scan

  1. Make sure you're scanning with WhatsApp (not camera app)
  2. Try regenerating: openclaw whatsapp link --force
  3. Check your phone has internet

AI Not Responding

  1. Check the gateway is running: openclaw gateway status
  2. Check API key is set: echo $ANTHROPIC_API_KEY
  3. Check logs: openclaw gateway logs

HubSpot Integration Not Working

  1. Verify token: curl -H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" https://api.hubapi.com/crm/v3/objects/contacts?limit=1
  2. Check scopes in HubSpot private app settings
  3. Ensure token isn't expired

What's Next?

You now have a working AI SDR foundation. Here's how to expand:

Week 1 additions:

  • Add more team members to the WhatsApp/Slack channel
  • Create 2-3 custom prompts for common requests
  • Set up one more automated daily report

Week 2 additions:

  • Add email integration for outbound drafts
  • Create a competitor research template
  • Build an objection handling reference

Week 3 additions:

  • Add Salesforce or other CRM if needed
  • Create multi-step workflows
  • Train team on best prompts

Resources

  • OpenClaw Docs: docs.openclaw.ai
  • Community Discord: discord.com/invite/clawd
  • GitHub: github.com/openclaw/openclaw
  • Skill Library: clawhub.com (pre-built automations)

Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

Want a Head Start?

MarketBetter builds on OpenClaw's foundation with pre-built GTM workflows, native HubSpot integration, and a complete SDR playbook—no setup required.

Book a Demo to see how we've productized the best of OpenClaw for sales teams.


Related reading:

Pricing Intelligence with AI: Track Competitor Pricing Changes in Real-Time [2026]

· 9 min read
MarketBetter Team
Content Team, marketbetter.ai

Your competitor just dropped their prices by 20%.

You find out when a prospect emails: "Why are you so much more expensive than [Competitor]?"

By then, you've already lost deals. Your sales team is blindsided. Your positioning is outdated.

Pricing intelligence used to require expensive tools or manual monitoring. Now, AI agents can track competitor pricing 24/7 — and alert you the moment something changes.

Pricing Intelligence Dashboard

Why Pricing Intelligence Matters More Than Ever

The reality of B2B pricing:

  • 62% of buyers compare pricing before talking to sales (Gartner)
  • 78% expect price transparency on websites (McKinsey)
  • Pricing page changes often signal strategy shifts
  • Your prospects are comparing you to 3-5 alternatives

What you're missing without monitoring:

  • New pricing tiers competitors launch
  • Promotional discounts and limited offers
  • Feature bundling changes
  • Free tier adjustments
  • Usage-based pricing tweaks
  • Contract term variations

The cost of being slow:

  • Lost deals to cheaper alternatives
  • Discounting when you didn't need to
  • Missing opportunities to raise prices
  • Sales conversations going sideways

Building Your AI Pricing Intelligence System

Component 1: Data Collection

What to monitor for each competitor:

Public pricing pages:

  • Tier names and prices
  • Feature lists per tier
  • Usage limits
  • Add-on pricing
  • Enterprise "contact us" language changes

Secondary sources:

  • G2/Capterra pricing mentions
  • LinkedIn posts about pricing
  • Press releases
  • Job postings (pricing analyst = incoming changes)
  • Customer reviews mentioning price
  • Discount codes circulating

Deal intelligence:

  • What prospects tell you they're being quoted
  • Win/loss analysis pricing mentions
  • Customer interview feedback

Component 2: Change Detection

Pricing Comparison Tracking

Use AI to detect meaningful changes:

const analyzePricingChange = async (competitor, previous, current) => {
const prompt = `
Analyze this competitor pricing change:

Competitor: ${competitor.name}

Previous pricing (captured ${previous.date}):
${JSON.stringify(previous.pricing, null, 2)}

Current pricing (captured ${current.date}):
${JSON.stringify(current.pricing, null, 2)}

Determine:
1. What specifically changed?
2. Significance level (major/moderate/minor)
3. Likely strategic intent
4. Impact on our competitive position
5. Recommended actions for our team

Consider:
- Price changes > 10% are significant
- New tier additions signal market expansion
- Feature changes indicate positioning shifts
- "Contact us" changes often precede price increases
`;

return await claude.analyze(prompt);
};

Sample output:

🚨 PRICING CHANGE DETECTED: Apollo
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Change Type: MAJOR
Detected: Feb 8, 2026 at 3:42 PM UTC

What Changed:
├─ Professional tier: $79 → $99/user/month (+25%)
├─ Team tier: $39 → $49/user/month (+26%)
├─ New "Starter" tier added at $29/user/month
└─ Annual discount reduced from 25% to 20%

Strategic Analysis:
Apollo is shifting upmarket while adding an entry-level tier. The 25%
price increase on Professional signals confidence in their enterprise
positioning. The new Starter tier suggests they're also protecting
against low-end competition (likely us and Seamless.AI).

Impact on MarketBetter:
- Our pricing now 15% lower than Apollo Professional (was 8%)
- We're competing directly with their new Starter tier
- Their annual discount cut improves our relative annual value

Recommended Actions:
1. Update sales battlecards — highlight our pricing advantage
2. Consider marketing campaign around "Apollo raised prices" angle
3. Target Apollo Starter users for upgrade messaging
4. Brief SDR team on change before tomorrow's calls

Confidence: 94%

Component 3: Automated Monitoring with OpenClaw

# pricing-intelligence-agent.yaml
name: Pricing Intelligence Monitor
schedule: "0 */4 * * *" # Every 4 hours

competitors:
- name: Apollo
url: https://www.apollo.io/pricing
selectors:
tiers: ".pricing-tier"
prices: ".tier-price"
features: ".feature-list"

- name: ZoomInfo
url: https://www.zoominfo.com/pricing
selectors:
tiers: ".pricing-card"
prices: ".price-amount"

- name: Outreach
url: https://www.outreach.io/pricing
selectors:
tiers: ".plan"
prices: ".plan-price"

workflow:
1_scrape:
action: web_scrape
targets: competitors
capture: [tiers, prices, features, last_modified]

2_compare:
action: ai_compare
model: claude-3-5-sonnet
against: previous_snapshot
threshold: any_change

3_analyze:
action: ai_analyze
model: claude-3-5-sonnet
prompt: pricing_change_analysis

4_alert:
condition: change_detected
actions:
- slack_notify: "#competitive-intel"
- email: ["sales-leadership@company.com"]
- update_battlecards: true
- log_to_database: true

5_archive:
action: save_snapshot
storage: pricing_history

Component 4: Trend Analysis

Don't just track changes — understand patterns:

const analyzePricingTrends = async (competitor, history) => {
const prompt = `
Analyze pricing trends for ${competitor.name}:

Historical pricing data (last 12 months):
${JSON.stringify(history, null, 2)}

Identify:
1. Overall price trajectory (increasing/stable/decreasing)
2. Pricing strategy pattern (premium/value/penetration)
3. Common timing of changes (quarterly? annual?)
4. Feature vs price trade-offs
5. Market positioning shifts
6. Predicted next move

Context:
- Industry average price increase: 5-8% annually
- Funding rounds often precede price changes
- Product launches typically add new tiers
`;

return await claude.analyze(prompt);
};

Output example:

📊 PRICING TREND ANALYSIS: ZoomInfo (12-month view)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Trajectory: ↗️ INCREASING
12-month change: +18% across all tiers
Pattern: Quarterly adjustments (Jan, Apr, Jul, Oct)

Key Observations:
1. Removed lowest tier in Q2 2025 (forcing upgrades)
2. Added "Lite" tier in Q3 2025 (response to competition)
3. Enterprise pricing became "contact us" only
4. Credits system introduced to limit data access

Strategy Assessment:
ZoomInfo is executing a classic "land and expand" price strategy:
- Entry tier for acquisition
- Usage limits force upgrades
- Enterprise opacity allows deal-specific pricing

Predicted Next Move:
Based on pattern, expect Q1 2026 adjustment:
- 5-10% increase on mid-tier (Professional)
- Possible new AI/enrichment add-on tier
- Further credit restrictions

Recommended Positioning:
Position against their credit model:
"Unlimited vs. ZoomInfo's metered access"

Advanced Use Cases

Use Case 1: Real-Time Deal Intelligence

When a prospect mentions competitor pricing:

const handlePricingMention = async (deal, competitorQuote) => {
const currentPricing = await getPricingSnapshot(competitorQuote.competitor);
const ourPricing = await calculateOurQuote(deal);

const analysis = await claude.analyze(`
Deal: ${deal.name} (${deal.value})

Competitor quote mentioned:
- Vendor: ${competitorQuote.competitor}
- Amount: ${competitorQuote.amount}
- Terms: ${competitorQuote.terms}

Our current pricing:
${JSON.stringify(ourPricing)}

Latest competitor public pricing:
${JSON.stringify(currentPricing)}

Determine:
1. Is their quote consistent with public pricing?
2. What discount % are they likely offering?
3. What's our competitive position?
4. Should we match, beat, or hold firm?
5. What value differentiation should we emphasize?
`);

return {
recommendation: analysis.recommendation,
discountSuggestion: analysis.discountSuggestion,
talkingPoints: analysis.talkingPoints,
riskLevel: analysis.riskLevel
};
};

Use Case 2: Win/Loss Pricing Analysis

const analyzePricingWinLoss = async (deals) => {
const prompt = `
Analyze our win/loss data for pricing patterns:

Last 100 deals:
${JSON.stringify(deals.map(d => ({
outcome: d.outcome,
ourPrice: d.ourPrice,
competitorPrice: d.competitorMentioned,
competitor: d.competitor,
lossReason: d.lossReason,
dealSize: d.value,
segment: d.segment
})))}

Find patterns:
1. Price sensitivity by segment
2. Competitors we lose to on price vs. value
3. Discount patterns in wins vs. losses
4. Optimal pricing by deal size
5. Feature gaps that justify price premium

Actionable insights for sales and pricing strategy.
`;

return await claude.analyze(prompt);
};

Output:

💰 WIN/LOSS PRICING ANALYSIS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Key Findings:

1. PRICE SENSITIVITY BY SEGMENT
- SMB (<50 employees): HIGH sensitivity
Lost 68% of deals where we were >20% more expensive
- Mid-market (50-500): MODERATE sensitivity
Won 55% even when 15% more expensive (value sold)
- Enterprise (500+): LOW sensitivity
Price mentioned in only 23% of losses

2. COMPETITOR-SPECIFIC PATTERNS
- vs. Apollo: Lost 70% when price-focused; Won 80% when value-focused
- vs. ZoomInfo: Price rarely competitive; Win on features
- vs. Seamless.AI: Must be within 10% to compete

3. OPTIMAL DISCOUNT STRATEGY
- SMB: Offer 15% discount proactively (win rate +34%)
- Mid-market: Hold firm, discount only for annual (win rate same)
- Enterprise: Discount range 10-25% acceptable

4. VALUE DIFFERENTIATION THAT JUSTIFIES PREMIUM
- Playbook feature: +22% price tolerance
- Visitor ID: +15% price tolerance
- Integration depth: +18% price tolerance

RECOMMENDATIONS:
├─ Create SMB-specific pricing tier
├─ Train SDRs on value selling for Apollo comparisons
├─ Develop "Total Cost of Ownership" calculator
└─ Document feature premium justifications

Use Case 3: Pricing Change Simulations

Before making your own pricing changes:

const simulatePriceChange = async (proposedChange) => {
const prompt = `
Simulate the impact of this pricing change:

Current pricing: ${JSON.stringify(currentPricing)}
Proposed change: ${JSON.stringify(proposedChange)}

Consider:
1. Competitor likely response
2. Customer segment impact
3. New customer acquisition effect
4. Existing customer reaction
5. Revenue impact (short and long-term)

Historical context:
- Last price increase: ${lastPriceChange.date} (${lastPriceChange.reaction})
- Competitor recent moves: ${competitorMoves}
- Market conditions: ${marketConditions}

Provide scenario analysis: best case, expected, worst case.
`;

return await claude.analyze(prompt);
};

Implementation Guide

Phase 1: Setup (Week 1)

Day 1-2: Identify competitors

  • List 5-10 direct competitors
  • Document their pricing page URLs
  • Note their pricing models (per seat, usage, flat)

Day 3-4: Configure scraping

  • Set up web scraping for each pricing page
  • Test selector accuracy
  • Handle dynamic content (JavaScript rendering)

Day 5: Baseline capture

  • Capture current pricing for all competitors
  • Verify accuracy against manual checks
  • Store initial snapshots

Phase 2: Automation (Week 2)

Day 1-2: OpenClaw agent setup

  • Configure monitoring schedule
  • Set up change detection thresholds
  • Test alert workflows

Day 3-4: Alert configuration

  • Slack integration for real-time alerts
  • Email digest for leadership
  • CRM integration for deal context

Day 5: Team training

  • Brief sales on using pricing intel
  • Show how to access competitor comparisons
  • Practice responding to pricing objections

Phase 3: Advanced (Week 3+)

  • Add secondary source monitoring (G2, press, social)
  • Build historical trend dashboards
  • Integrate with deal intelligence
  • Train win/loss pricing models

ROI Calculation

Costs:

  • AI API: ~$50/month (monitoring + analysis)
  • Web scraping infrastructure: ~$20/month
  • Setup time: ~20 hours

Benefits:

  • Faster response to pricing changes: Save 1 deal/month = $10K+ ARR
  • Better discounting decisions: Reduce unnecessary discounts by 3% = $15K/year
  • Competitive positioning: Win 2 extra deals/quarter = $40K ARR
  • Strategic pricing moves: 5% price increase enabled = Variable

Conservative ROI: $50K+ annual value vs. $1K annual cost = 50x ROI


Free Tool

Try our Tech Stack Detector — instantly detect any company's tech stack from their website. No signup required.

Start Tracking Today

Your competitors are changing their pricing constantly. Without intelligence, you're always reacting.

AI makes pricing intelligence accessible to any team — not just enterprises with dedicated competitive intelligence staff.

Your next steps:

  1. List your top 5 competitors and their pricing URLs
  2. Set up basic web monitoring
  3. Book a demo with MarketBetter to see competitive intelligence automation in action

Because the best pricing strategy starts with knowing what you're competing against.

Build a Revenue Operations Dashboard with Claude Code [2026]

· 9 min read
Sunder Iyer
Founder, marketbetter.ai

Your CRO asks: "Are we going to hit the number this month?"

You spend 4 hours pulling data from HubSpot, cross-referencing with finance, adjusting for pipeline weighting, and building a slide deck. By the time you present it, the data is 3 days old.

This is RevOps in 2025. It doesn't have to be RevOps in 2026.

With Claude Code, you can build a real-time revenue dashboard that:

  • Pulls live data from CRM, marketing, and finance systems
  • Automatically weights pipeline by historical close rates
  • Surfaces risks before they become surprises
  • Updates continuously, not monthly

Here's exactly how to build it.

RevOps dashboard architecture

Why Your Current Dashboards Fail

Problem 1: Data silos Pipeline is in HubSpot. Bookings are in the finance system. Marketing attribution is in Marketo. Usage data is in the product. Getting a complete picture requires manual assembly.

Problem 2: Stale data Weekly pipeline reviews use data that's already a week old. Monthly board decks are historical artifacts by the time they're presented.

Problem 3: No intelligence Dashboards show what happened, not what's likely to happen. They can't answer "should I be worried about this deal?"

Problem 4: Too many dashboards HubSpot has reports. Tableau has dashboards. Looker has boards. Nobody knows which one is "the truth."

The RevOps Dashboard Architecture

Here's what we're building:

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ HubSpot │ │ Stripe │ │ Marketo │
│ (CRM) │ │ (Revenue) │ │ (Marketing) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
▼ ▼ ▼
┌────────────────────────────────────────────────────┐
│ Data Normalization Layer │
│ (Claude Code - ETL + Enrichment) │
└───────────────────────┬────────────────────────────┘


┌────────────────────────────────────────────────────┐
│ Analytics Engine │
│ - Pipeline weighting │
│ - Forecasting models │
│ - Risk scoring │
│ - Attribution analysis │
└───────────────────────┬────────────────────────────┘


┌────────────────────────────────────────────────────┐
│ Executive Dashboard │
│ - Real-time metrics │
│ - Drill-down capability │
│ - AI-generated insights │
└────────────────────────────────────────────────────┘

Step 1: Data Integration with Claude Code

Let Claude Code build your data pipeline:

claude "Create a TypeScript module that:
1. Pulls deal data from HubSpot (all deals, all stages, with history)
2. Pulls revenue data from Stripe (MRR, ARR, churn, expansion)
3. Pulls campaign data from HubSpot Marketing (attribution, source)
4. Normalizes dates and amounts to consistent formats
5. Handles pagination and rate limiting
6. Stores in PostgreSQL with proper indexing

Use environment variables for API keys. Include comprehensive error handling."

Claude's 200K context window means you can provide full API documentation and get back production-ready code—not snippets that need assembly.

Sample Data Normalization

// data-pipeline.ts - Claude Code generated

interface UnifiedDeal {
id: string;
name: string;
company: string;
amount: number;
currency: 'USD';
stage: string;
stageHistory: StageChange[];
probability: number;
owner: User;
source: MarketingSource;
closeDate: Date;
createdAt: Date;
daysInStage: number;
lastActivity: Date;
contacts: Contact[];
}

const normalizeDeal = (hubspotDeal: HubSpotDeal): UnifiedDeal => {
return {
id: hubspotDeal.id,
name: hubspotDeal.properties.dealname,
company: hubspotDeal.associations?.companies?.[0]?.name || 'Unknown',
amount: normalizeAmount(
hubspotDeal.properties.amount,
hubspotDeal.properties.deal_currency_code
),
currency: 'USD',
stage: mapStage(hubspotDeal.properties.dealstage),
stageHistory: parseStageHistory(hubspotDeal),
probability: calculateProbability(hubspotDeal),
owner: await getOwner(hubspotDeal.properties.hubspot_owner_id),
source: await getAttribution(hubspotDeal),
closeDate: new Date(hubspotDeal.properties.closedate),
createdAt: new Date(hubspotDeal.properties.createdate),
daysInStage: calculateDaysInStage(hubspotDeal),
lastActivity: await getLastActivity(hubspotDeal.id),
contacts: await getContacts(hubspotDeal.id)
};
};

Step 2: Intelligent Pipeline Weighting

Raw pipeline is a fantasy number. Weighted pipeline predicts reality:

// pipeline-weighting.ts

interface WeightingModel {
byStage: Record<string, number>; // Historical close rates by stage
byAgeInStage: (stage: string, days: number) => number; // Decay factor
bySource: Record<string, number>; // Source quality multiplier
byDealSize: (amount: number) => number; // Large deal discount
}

const buildWeightingModel = async (): Promise<WeightingModel> => {
// Analyze last 12 months of closed deals
const closedWon = await getClosedWonDeals('12m');
const closedLost = await getClosedLostDeals('12m');

// Calculate actual close rates by stage
const byStage = calculateStageConversion(closedWon, closedLost);
// Example result:
// { 'Discovery': 0.12, 'Demo': 0.34, 'Proposal': 0.62, 'Negotiation': 0.78 }

// Calculate age decay
const byAgeInStage = buildDecayFunction(closedWon, closedLost);
// Example: Deals 2x average time in stage close at 40% the rate

// Calculate source quality
const bySource = calculateSourceQuality(closedWon);
// Example: { 'Inbound': 1.2, 'Outbound': 0.8, 'Partner': 1.1, 'Event': 0.7 }

// Calculate deal size impact
const byDealSize = buildSizeFunction(closedWon, closedLost);
// Example: Deals >$100K close at 70% the rate of average deals

return { byStage, byAgeInStage, bySource, byDealSize };
};

const weightDeal = (deal: UnifiedDeal, model: WeightingModel): number => {
const baseWeight = model.byStage[deal.stage] || 0.1;
const ageMultiplier = model.byAgeInStage(deal.stage, deal.daysInStage);
const sourceMultiplier = model.bySource[deal.source.channel] || 1;
const sizeMultiplier = model.byDealSize(deal.amount);

return deal.amount * baseWeight * ageMultiplier * sourceMultiplier * sizeMultiplier;
};

Step 3: Risk Scoring

Identify deals that need attention before they slip:

// risk-scoring.ts

interface DealRisk {
dealId: string;
score: number; // 0-100, higher = more risk
factors: RiskFactor[];
recommendation: string;
}

const calculateDealRisk = async (deal: UnifiedDeal): Promise<DealRisk> => {
const factors: RiskFactor[] = [];
let score = 0;

// Time in stage risk
const avgTimeInStage = await getAverageTimeInStage(deal.stage);
if (deal.daysInStage > avgTimeInStage * 1.5) {
score += 25;
factors.push({
type: 'stale',
description: `${deal.daysInStage} days in ${deal.stage} (avg: ${avgTimeInStage})`,
severity: 'high'
});
}

// Activity recency risk
const daysSinceActivity = daysBetween(deal.lastActivity, new Date());
if (daysSinceActivity > 14) {
score += 20;
factors.push({
type: 'inactive',
description: `No activity in ${daysSinceActivity} days`,
severity: 'medium'
});
}

// Close date risk
const daysToClose = daysBetween(new Date(), deal.closeDate);
if (daysToClose < 14 && deal.stage !== 'Negotiation') {
score += 30;
factors.push({
type: 'unrealistic_date',
description: `Closing in ${daysToClose} days but still in ${deal.stage}`,
severity: 'high'
});
}

// Champion identified
const hasChampion = deal.contacts.some(c => c.role === 'Champion');
if (!hasChampion && deal.amount > 50000) {
score += 15;
factors.push({
type: 'no_champion',
description: 'No champion identified on $50K+ deal',
severity: 'medium'
});
}

// Generate recommendation
const recommendation = await generateRecommendation(deal, factors);

return { dealId: deal.id, score, factors, recommendation };
};

Step 4: The Dashboard

Build a clean, executive-ready interface:

// dashboard.ts

interface ExecutiveDashboard {
// The Numbers
currentMonth: {
target: number;
closed: number;
committed: number; // High-confidence pipeline
bestCase: number; // Weighted pipeline
gap: number;
};

// Pipeline Health
pipeline: {
total: number;
weighted: number;
byStage: Record<string, { count: number; value: number; weighted: number }>;
created: { thisMonth: number; lastMonth: number; change: number };
velocity: { avgDaysToClose: number; trend: 'faster' | 'slower' | 'stable' };
};

// Risks & Opportunities
risks: DealRisk[];
stuckDeals: UnifiedDeal[];
pushedDeals: UnifiedDeal[]; // Close date moved out
bigMoves: UnifiedDeal[]; // Stage changed this week

// Trends
trends: {
winRate: { current: number; previous: number; change: number };
avgDealSize: { current: number; previous: number; change: number };
salesCycle: { current: number; previous: number; change: number };
};

// AI Insights
insights: string[];
}

const buildDashboard = async (): Promise<ExecutiveDashboard> => {
const deals = await getAllDeals();
const model = await buildWeightingModel();

// Calculate metrics
const currentMonth = await calculateMonthMetrics(deals, model);
const pipeline = await analyzePipeline(deals, model);
const risks = await Promise.all(
deals
.filter(d => d.stage !== 'Closed Won' && d.stage !== 'Closed Lost')
.map(d => calculateDealRisk(d))
);

// Generate AI insights
const insights = await generateInsights({
currentMonth,
pipeline,
risks: risks.filter(r => r.score > 50)
});

return {
currentMonth,
pipeline,
risks: risks.sort((a, b) => b.score - a.score).slice(0, 10),
stuckDeals: deals.filter(d => isStuck(d)).slice(0, 5),
pushedDeals: await getPushedDeals('7d'),
bigMoves: await getBigMoves('7d'),
trends: await calculateTrends(),
insights
};
};

RevOps dashboard data flow

Step 5: AI-Generated Insights

The dashboard doesn't just show data—it explains it:

// insights.ts

const generateInsights = async (data: DashboardData): Promise<string[]> => {
const prompt = `
You are a RevOps analyst. Based on this data, provide 3-5 key insights
that would be valuable for a CRO in their Monday morning review.

Be specific. Use numbers. Flag concerns. Highlight wins.

Data:
- Target: $${data.currentMonth.target.toLocaleString()}
- Closed: $${data.currentMonth.closed.toLocaleString()} (${(data.currentMonth.closed / data.currentMonth.target * 100).toFixed(0)}% of target)
- Committed: $${data.currentMonth.committed.toLocaleString()}
- High-risk deals: ${data.risks.filter(r => r.score > 70).length}
- Deals pushed this week: ${data.pushedDeals.length}
- Win rate trend: ${data.trends.winRate.change > 0 ? 'up' : 'down'} ${Math.abs(data.trends.winRate.change)}%

Format as bullet points, no headers.
`;

const response = await claude.complete(prompt);
return response.split('\n').filter(line => line.startsWith('-') || line.startsWith('•'));
};

Example output:

On track but tight: At 68% of target with 12 days left. Need $127K from committed pipeline that's currently weighted at $143K. No buffer.

Acme Corp is the swing deal: $85K deal in Negotiation, but 23 days in stage (avg: 11). Risk score 78. Recommend: exec-to-exec call before Friday.

Win rate improving: 34% this month vs 28% last month. Driven by better qualification—MQL rejection rate up 15%.

Pipeline generation concern: Only $340K created this month vs $520K target. Marketing sourced leads down 22%. Check campaign performance.

3 deals pushed close dates this week totaling $124K. Pattern: all had unrealistic close dates set during initial discovery. Consider discovery checklist update.

Automated Distribution

Push insights where people actually look:

// distribution.ts

// Monday morning CRO briefing
const mondayBriefing = async () => {
const dashboard = await buildDashboard();

await slack.postMessage({
channel: '#revenue-leadership',
blocks: [
{
type: 'header',
text: { type: 'plain_text', text: '📊 Monday Revenue Brief' }
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*Closed:* $${dashboard.currentMonth.closed.toLocaleString()}` },
{ type: 'mrkdwn', text: `*Target:* $${dashboard.currentMonth.target.toLocaleString()}` },
{ type: 'mrkdwn', text: `*Committed:* $${dashboard.currentMonth.committed.toLocaleString()}` },
{ type: 'mrkdwn', text: `*Gap:* $${dashboard.currentMonth.gap.toLocaleString()}` }
]
},
{
type: 'section',
text: {
type: 'mrkdwn',
text: `*AI Insights:*\n${dashboard.insights.join('\n')}`
}
}
]
});
};

// Daily risk alerts
const dailyRiskAlerts = async () => {
const dashboard = await buildDashboard();
const criticalRisks = dashboard.risks.filter(r => r.score > 70);

if (criticalRisks.length > 0) {
for (const risk of criticalRisks) {
const deal = await getDeal(risk.dealId);

await slack.postMessage({
channel: deal.owner.slackId,
text: `⚠️ Risk alert on *${deal.name}* ($${deal.amount.toLocaleString()})\n\n${risk.factors.map(f => `${f.description}`).join('\n')}\n\n*Recommendation:* ${risk.recommendation}`
});
}
}
};

Implementation Timeline

Week 1: Data Layer

  • Set up PostgreSQL database
  • Build HubSpot integration
  • Build Stripe integration (if applicable)
  • Create normalization layer

Week 2: Analytics

  • Implement weighting model from historical data
  • Build risk scoring
  • Create trend calculations

Week 3: Dashboard

  • Build dashboard API
  • Create frontend (or use existing BI tool)
  • Integrate AI insights

Week 4: Distribution

  • Set up Slack integrations
  • Configure automated briefings
  • Train team on using the dashboard

The ROI

MetricBeforeAfter
Time to answer "how are we doing?"4 hours10 seconds
Pipeline accuracy60%85%
Deals slipping unnoticed5-7/month0-1/month
Forecast variance±25%±10%
Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

What's Next?

Once your RevOps dashboard is running:

  1. Add product usage data — See which customers are actually using what they bought
  2. Build scenario modeling — "What if we slip these 3 deals?"
  3. Connect to capacity planning — Does pipeline support hiring plan?
  4. Enable board reporting — Auto-generate monthly investor updates

Ready to stop guessing and start knowing? Book a demo to see how MarketBetter combines real-time intelligence with AI-powered workflows.

Related reading:

AI-Powered SDR Performance Benchmarking with Codex [2026]

· 7 min read
Sunder Iyer
Founder, marketbetter.ai

"How do I know if my SDRs are actually performing well?"

Every sales leader asks this question. And most answer it with vibes instead of data.

You compare reps against each other (which creates toxic competition). You look at quota attainment (which ignores activity quality). You check dashboards that show what happened but not why.

What if you could automatically benchmark every rep against:

  • Their own historical performance
  • Team averages
  • Industry standards
  • Top performer patterns

That's what we're building today using GPT-5.3 Codex.

SDR performance benchmarking dashboard

Why Traditional Benchmarking Fails

Most SDR benchmarking is broken because it measures the wrong things:

Problem 1: Vanity metrics Tracking "emails sent" rewards volume over quality. A rep sending 200 garbage emails looks better than one sending 50 personalized messages that book meetings.

Problem 2: Outcome bias Some reps get better territories or warmer leads. Comparing raw meeting counts ignores the inputs.

Problem 3: Lag indicators only By the time quota attainment shows a problem, it's too late. You need leading indicators.

Problem 4: Manual analysis RevOps pulls reports quarterly, builds a deck, presents to leadership. By then the data is stale.

The AI Benchmarking Framework

Here's how to build a real-time, AI-powered benchmarking system:

Metrics That Actually Matter

Activity Quality Metrics:

MetricWhat It MeasuresWhy It Matters
Response Rate% of outreach getting repliesShows message resonance
Positive Response Rate% of replies that are interestedFilters out "unsubscribe" replies
Personalization ScoreAI-assessed email customizationPredicts engagement
Sequence Completion% of prospects going through full sequenceShows follow-up discipline

Efficiency Metrics:

MetricWhat It MeasuresWhy It Matters
Activities per MeetingHow many touches to bookEfficiency indicator
Time to First MeetingDays from lead assignment to demoSpeed metric
Connect Rate% of calls that reach a personDialing effectiveness
Talk Time RatioTime talking vs listening on callsConversation quality

Conversion Metrics:

MetricWhat It MeasuresWhy It Matters
MQL to SQL Rate% of leads that become opportunitiesQuality of qualification
Meeting Show Rate% of booked meetings that happenQualifying strength
Pipeline GeneratedDollar value createdUltimate output

Building the Benchmarking System

Step 1: Data Collection with Codex

First, use Codex to build a data extraction pipeline:

codex "Create a Node.js script that:
1. Pulls activity data from HubSpot for all sales users
2. Categorizes activities by type (email, call, meeting, LinkedIn)
3. Calculates daily/weekly/monthly aggregates per rep
4. Stores results in a PostgreSQL database

Include error handling and rate limiting for the HubSpot API."

Codex's mid-turn steering is perfect here—you can refine the output as it generates:

"Actually, also include email open rates and click rates from the engagement data."

Step 2: Benchmark Calculation

Now create the benchmarking logic:

// benchmarks.js - Generated and refined with Codex

const calculateBenchmarks = async (repId, timeframe = '30d') => {
const repData = await getRepMetrics(repId, timeframe);
const teamData = await getTeamMetrics(timeframe);
const historicalData = await getRepHistorical(repId, '90d');

return {
rep: repId,
period: timeframe,

// Compare to team
vsTeam: {
emailResponseRate: {
rep: repData.emailResponseRate,
teamAvg: teamData.avgEmailResponseRate,
percentile: calculatePercentile(repData.emailResponseRate, teamData.allEmailResponseRates),
delta: ((repData.emailResponseRate - teamData.avgEmailResponseRate) / teamData.avgEmailResponseRate * 100).toFixed(1)
},
meetingsBooked: {
rep: repData.meetingsBooked,
teamAvg: teamData.avgMeetingsBooked,
percentile: calculatePercentile(repData.meetingsBooked, teamData.allMeetingsBooked),
delta: ((repData.meetingsBooked - teamData.avgMeetingsBooked) / teamData.avgMeetingsBooked * 100).toFixed(1)
},
activitiesPerMeeting: {
rep: repData.activitiesPerMeeting,
teamAvg: teamData.avgActivitiesPerMeeting,
// Lower is better here
percentile: 100 - calculatePercentile(repData.activitiesPerMeeting, teamData.allActivitiesPerMeeting),
delta: ((teamData.avgActivitiesPerMeeting - repData.activitiesPerMeeting) / teamData.avgActivitiesPerMeeting * 100).toFixed(1)
}
},

// Compare to self
vsSelf: {
emailResponseRate: {
current: repData.emailResponseRate,
previous: historicalData.avgEmailResponseRate,
trend: repData.emailResponseRate > historicalData.avgEmailResponseRate ? 'improving' : 'declining'
},
meetingsBooked: {
current: repData.meetingsBooked,
previous: historicalData.avgMeetingsBooked,
trend: repData.meetingsBooked > historicalData.avgMeetingsBooked ? 'improving' : 'declining'
}
},

// Industry benchmarks (from Bridge Group, Gartner, etc.)
vsIndustry: {
emailResponseRate: {
rep: repData.emailResponseRate,
industryAvg: 0.023, // 2.3% is typical B2B cold email
status: repData.emailResponseRate > 0.023 ? 'above' : 'below'
},
connectRate: {
rep: repData.connectRate,
industryAvg: 0.028, // 2.8% typical cold call connect
status: repData.connectRate > 0.028 ? 'above' : 'below'
},
meetingsPerMonth: {
rep: repData.meetingsBooked,
industryAvg: 12, // Typical SDR quota
status: repData.meetingsBooked >= 12 ? 'on pace' : 'below pace'
}
}
};
};

Step 3: Pattern Analysis

This is where AI really shines—identifying what top performers do differently:

// pattern-analysis.js

const analyzeTopPerformers = async () => {
const topReps = await getRepsAbovePercentile(90);
const patterns = {};

// Time patterns
patterns.emailTiming = analyzeEmailSendTimes(topReps);
// Result: "Top performers send emails Tuesday-Thursday, 7-9am local time"

// Sequence patterns
patterns.sequenceLength = analyzeSequenceLengths(topReps);
// Result: "Top performers use 7-touch sequences, not 12"

// Content patterns
patterns.subjectLines = await analyzeSubjectLines(topReps);
// Result: "Top performers use questions and specific pain points"

// Call patterns
patterns.callBehavior = analyzeCallMetrics(topReps);
// Result: "Top performers have 2:1 listen-to-talk ratio"

return patterns;
};

Step 4: Automated Insights

Don't just show data—generate recommendations:

// insights.js - AI-generated analysis

const generateRepInsights = async (repId) => {
const benchmarks = await calculateBenchmarks(repId);
const patterns = await analyzeTopPerformers();
const repBehavior = await getRepBehaviorData(repId);

const prompt = `
Analyze this SDR's performance and provide 3 specific, actionable recommendations.

Rep Benchmarks: ${JSON.stringify(benchmarks)}
Top Performer Patterns: ${JSON.stringify(patterns)}
Rep Behavior Data: ${JSON.stringify(repBehavior)}

Format as:
1. [Specific Issue]: [Concrete Action]

Be direct. No fluff.
`;

const insights = await claude.complete(prompt);
return insights;
};

Example output:

Insights for Marcus Chen - Feb 2026

  1. Email timing is off: You send most emails at 2pm when open rates are 12%. Top performers send 7-9am when rates hit 28%. Action: Reschedule email sends in your sequence settings.

  2. Sequence too long: Your 12-step sequence has 4% completion. Team average 7-step sequence has 34% completion. Prospects ghost after step 6. Action: Condense to 7 touches, make final touch a breakup email.

  3. Call talk ratio inverted: You talk 68% of calls. Top performers listen 65% of calls. Prospects who talk more are 2x more likely to book. Action: Ask more open-ended questions, especially about current process.

SDR performance benchmark comparison

Deploying to Slack

Make this actionable by pushing to where reps already work:

// Weekly benchmark report - OpenClaw cron

const weeklyBenchmarkReport = async () => {
for (const rep of salesTeam) {
const benchmarks = await calculateBenchmarks(rep.id, '7d');
const insights = await generateRepInsights(rep.id);

await slack.postMessage({
channel: rep.slackDm,
blocks: [
{
type: "header",
text: { type: "plain_text", text: "📊 Your Weekly Performance" }
},
{
type: "section",
text: {
type: "mrkdwn",
text: `*Response Rate:* ${benchmarks.vsTeam.emailResponseRate.rep}% (Team avg: ${benchmarks.vsTeam.emailResponseRate.teamAvg}%)\n*Meetings:* ${benchmarks.vsTeam.meetingsBooked.rep} (${benchmarks.vsTeam.meetingsBooked.delta}% vs team)\n*Efficiency:* ${benchmarks.vsTeam.activitiesPerMeeting.rep} activities per meeting`
}
},
{
type: "section",
text: {
type: "mrkdwn",
text: `*🎯 This Week's Focus:*\n${insights}`
}
}
]
});
}
};

Manager Dashboard

Leadership needs aggregate views:

// manager-view.js

const generateManagerDashboard = async (managerId) => {
const team = await getTeamByManager(managerId);

const dashboard = {
teamHealth: {
onPace: team.filter(r => r.pipelineGenerated >= r.quota * 0.9).length,
atRisk: team.filter(r => r.pipelineGenerated < r.quota * 0.7).length,
total: team.length
},

topPerformers: team
.sort((a, b) => b.percentileRank - a.percentileRank)
.slice(0, 3)
.map(r => ({ name: r.name, highlight: r.topMetric })),

needsAttention: team
.filter(r => r.trend === 'declining' || r.percentileRank < 25)
.map(r => ({
name: r.name,
issue: r.biggestGap,
recommendation: r.topInsight
})),

teamPatterns: {
bestDay: findBestPerformingDay(team),
worstDay: findWorstPerformingDay(team),
commonBlocker: findCommonIssue(team)
}
};

return dashboard;
};

Real Impact Numbers

Teams using AI-powered benchmarking see:

MetricBeforeAfterChange
Time spent on performance reviews4 hrs/week30 min/week-87%
Reps hitting quota48%67%+40%
Underperformance detection time45 days7 days-84%
Coaching session effectiveness"okay"TargetedQualitative

Getting Started

Here's your implementation plan:

Week 1: Data Foundation

  • Audit what activity data you have in your CRM
  • Use Codex to build extraction scripts
  • Set up a simple database for metrics

Week 2: Benchmark Logic

  • Implement team comparison calculations
  • Add industry benchmarks from reports
  • Build self-comparison (vs historical)

Week 3: AI Analysis

  • Connect Claude for insight generation
  • Analyze top performer patterns
  • Create recommendation engine

Week 4: Distribution

  • Build Slack notifications
  • Create manager dashboards
  • Train team on using insights
Free Tool

Try our AI Lead Generator — find verified LinkedIn leads for any company instantly. No signup required.

What's Next?

Once benchmarking is running, you can:

  1. Predict quota attainment — Use leading indicators to forecast before month-end
  2. Auto-assign coaching — Route struggling reps to training automatically
  3. Territory optimization — Rebalance based on performance capacity
  4. Hiring profiles — Model what makes reps successful to improve recruiting

The goal isn't surveillance—it's helping every rep become a top performer.


Ready to stop guessing and start measuring? Book a demo to see how MarketBetter combines AI-powered insights with SDR workflow automation.

Related reading: