If you landed here you probably typed something like “OpenClaw sales prospecting and outreach automation setup” into DuckDuckGo, got tired of one-page templates, and want actual instructions. I spent the last month moving our outbound stack from a Typeform-Zapier spaghetti to OpenClaw 4.5 running on ClawCloud. Below is everything that worked, broke, and finally shipped. Copy-paste, fork, tweak—just don’t spray spam.

Why OpenClaw for outbound automation?

I tried HubSpot Sequences (works but $$$), Lemlist (great UI, closed box), and a homemade Node cron (cheap, brittle). OpenClaw sits in the sweet spot:

  • Programmable. Written in Node 22+. You own the logic, you commit it.
  • 800+ integrations via Composio. Gmail, Outlook, LinkedIn, Clearbit, Apollo, HubSpot, Salesforce—the usual suspects.
  • Browser + shell tools. Scrape LinkedIn, call Clearbit API, write to PostgreSQL in one workflow.
  • Runs everywhere. npm i -g openclaw@4.5.1 on your laptop, or spin a ClawCloud agent in 60 seconds.
  • Transparent. Every outbound step is logged. If legal ever asks how a contact got emailed, you have the trace.

The trade-offs: you write JavaScript/TypeScript instead of clicking a UI; and you’re responsible for not turning your domain into a spam penalty.

Prerequisites and versions

  • Node 22.2+ (nvm install 22)
  • OpenClaw 4.5.1 (npm i -g openclaw@4.5.1)
  • ClawCloud account (free tier is fine; gives 2 agents, 5k runs/month)
  • Gmail or Microsoft 365 mailbox with API access
  • LinkedIn Sales Navigator seat (or risk getting throttled)
  • Clearbit or Apollo API key for enrichment
  • HubSpot dev account for CRM sync
  • SPF, DKIM, DMARC properly configured on your sending domain before you start. No shortcuts here.

Building the lead list (Clearbit + Apollo + sheets)

I like starting from a broad CSV, then filtering using Clearbit’s enrichment endpoint and Apollo’s job title search. OpenClaw lets you chain those calls without extra servers.

1. Bootstrap the agent

openclaw init outbound-bot cd outbound-bot npm i @composio/sdk clearbit apollo-client csv-parse

2. Define the workflow

// workflows/leadEnrichment.ts import { workflow, shell } from 'openclaw'; import { parse } from 'csv-parse/sync'; import fs from 'node:fs'; import Clearbit from 'clearbit'; import { ApolloClient, InMemoryCache, gql } from '@apollo/client/core'; export default workflow('lead-enrichment', async (ctx) => { const rawCsv = fs.readFileSync('raw.csv', 'utf8'); const rows = parse(rawCsv, { columns: true }); const clearbit = Clearbit(process.env.CLEARBIT_KEY); const apollo = new ApolloClient({ uri: 'https://api.apollo.io/graphql', cache: new InMemoryCache(), headers: { 'Api-Key': process.env.APOLLO_KEY } }); const enriched: any[] = []; for (const r of rows) { const person = await clearbit.Person.find({ email: r.email }).catch(() => null); if (!person) continue; const titleQuery = await apollo.query({ query: gql`query ($email: String!){ person(email: $email){ title } }`, variables: { email: r.email } }); if (/director|vp|head/i.test(titleQuery.data.person.title)) { enriched.push({ ...r, title: titleQuery.data.person.title }); } } fs.writeFileSync('enriched.csv', enriched.map(e => Object.values(e).join(',')).join('\n')); await ctx.log(`Enriched list size: ${enriched.length}`); });

Commit, push, then schedule daily:

openclaw schedule lead-enrichment "0 3 * * 1-5" # 3 AM UTC weekdays

On ClawCloud the scheduler is handled by the daemon, so it keeps running even if your laptop is closed.

Email outreach sequence with OpenClaw scheduler and Resend

For deliverability I prefer a dedicated sub-domain (mail.example.com) and Resend’s API. OpenClaw’s @tools/email wrapper handles throttling (max 200/day by default) so you don’t nuke your reputation.

1. Create the sequence template

// templates/product-demo.mjml Subject: {{firstName}}, quick question about {{company}} --- Hi {{firstName}}, We built a platform that automates {{painPoint}}. Worth a 10-min chat? Thanks, {{senderName}}

Put follow-ups in the same MJML file separated by ---. The email tool parses and schedules them D+3, D+7, etc.

2. Wire the workflow

// workflows/emailSequence.ts import { workflow } from 'openclaw'; import { sendSequence } from '@tools/email'; import fs from 'node:fs'; import { parse } from 'csv-parse/sync'; export default workflow('email-sequence', async (ctx) => { const csv = fs.readFileSync('enriched.csv', 'utf8'); const leads = parse(csv, { columns: true }); for (const lead of leads) { await sendSequence({ to: lead.email, data: { firstName: lead.first_name, company: lead.company, painPoint: 'monthly reporting', senderName: 'Peter at OpenClaw' }, template: 'product-demo.mjml', meta: { list: 'May-dev-tools' } }); } });

3. Throttle and schedule

openclaw schedule email-sequence "30 3 * * 1-5" --concurrency 20 --delay 60

This fires 20 emails in parallel, then sleeps 60 seconds. Resend logs the rest. If you prefer Gmail API, swap sendSequence with @tools/gmail.

LinkedIn connection automation with the browser tool

LinkedIn doesn’t expose an official API for connection requests. The community built slick Puppeteer scripts, but OpenClaw’s built-in browser tool wraps Playwright under the hood and keeps headless Chrome patched.

1. Store cookies securely

openclaw secrets set LINKEDIN_COOKIES "li_at=...; li_a="

2. Workflow snippet

// workflows/linkedinConnect.ts import { workflow, browser } from 'openclaw'; import fs from 'node:fs'; import { parse } from 'csv-parse/sync'; export default workflow('linkedin-connect', async (ctx) => { const leads = parse(fs.readFileSync('enriched.csv', 'utf8'), { columns: true }); const page = await browser.newPage({ cookies: process.env.LINKEDIN_COOKIES }); for (const lead of leads.slice(0, 50)) { // stay sane: 50/day await page.goto(`https://www.linkedin.com/in/${lead.linkedin_slug}`); const button = await page.waitForSelector('button[aria-label^="Connect"]', { timeout: 5000 }).catch(() => null); if (!button) continue; await button.click(); await page.click('button[aria-label="Send now"]'); await ctx.log(`Invited ${lead.first_name}`); await page.waitForTimeout(30000 + Math.random() * 15000); // 30-45 s human gap } });

Run it locally first. If LinkedIn shows captcha more than two times, cut your volume. Once stable, schedule:

openclaw schedule linkedin-connect "15 4 * * 2-6"

ClawCloud takes care of the headless browser. The agent shuts down after completion, so you’re not billed extra hours.

Follow-up tracking and CRM sync (HubSpot example)

Email opens are a noisy metric but still useful for prioritizing calls. We’ll push events to HubSpot and create tasks for reps.

1. Webhook the email events

openclaw listen email.events --port 4242

Resend (or Postmark) can POST to /email/events. OpenClaw maps it to a workflow:

// workflows/onEmailEvent.ts import { workflow } from 'openclaw'; import HubSpot from '@hubspot/api-client'; export default workflow('on-email-event', async (ctx) => { const { type, email, meta } = ctx.event.body; if (type !== 'open') return; // only care about opens const hubspot = new HubSpot({ apiKey: process.env.HUBSPOT_KEY }); const [contact] = await hubspot.crm.contacts.searchApi.doSearch({ filterGroups: [{ filters: [{ propertyName: 'email', operator: 'EQ', value: email }] }], properties: ['email'] }); if (!contact) return; await hubspot.crm.tasks.basicApi.create({ properties: { hs_task_body: `Email opened. Call ${email}`, hs_task_priority: 'HIGH', hubspot_owner_id: '80791234', hs_timestamp: Date.now() + 1000 * 60 * 60 * 2 // due in 2h }, associations: [{ id: contact.id, type: 'contact' }] }); });

HubSpot limits 100k API calls/day. OpenClaw automatically retries 429s with exponential backoff; still, batch your events.

Putting it together: the master gateway config

The gateway is the web UI you’ll load to monitor runs. Point it to all workflows:

// gateway.config.js export default { workflows: [ './workflows/leadEnrichment.ts', './workflows/emailSequence.ts', './workflows/linkedinConnect.ts', './workflows/onEmailEvent.ts' ], memory: 'redis://default:redispw@redis-18482.us-east-1.claw:6379', auth: { users: [ { email: 'saleslead@example.com', role: 'admin' }, { email: 'bd@example.com', role: 'viewer' } ] } };

Deploy:

git push claw main

ClawCloud runs openclaw gateway --port $PORT under the hood and streams logs to the dashboard. You get a public endpoint (behind Cloudflare) plus VPC access for the daemon.

Ethical & compliance guardrails

I wish this section were optional, but regulators disagree. Here’s what we do:

  • Consent buckets. All leads from trade shows go to a separate list flagged source=consented. Workflows skip the generic cold sequence for those.
  • One sequence per recipient. We store a hash sha256(email+sequenceId) in Redis. If present, abort. Prevents duplicates when ops rerun jobs.
  • Rate limits. 200 emails/day per domain, 50 LinkedIn requests/day per seat. Anything higher trips spam filters.
  • Unsubscribe header. Resend needs List-Unsubscribe. We inject: <mailto:unsubscribe@example.com?subject=unsubscribe&body={{uuid}}>
  • GDPR log. Every enrichment call stores { email, source, timestamp } in Postgres. Data Protection Officer can export on demand.
  • Audit webhook. OpenClaw emits workflow.completed JSON to our SIEM. Non-sales people can audit what went out.

Community tip: several users reported Gmail’s new 0.3% spam complaint rule biting them. Our bounce rate went down after adding images no larger than 20 KB and SPF + DKIM + DMARC alignment.

Debugging and scaling

1. Local dry runs

openclaw run email-sequence --dry --limit 3

Sends to example.com sink addresses, renders MJML to ./outbox for manual inspection.

2. Production logs

ClawCloud exposes agent_id.log.claw.dev. Tail:

openclaw logs --agent outbound-bot --follow

3. Horizontal scale

Need more than 5k emails/day? Spin additional agents on sub-domains (sales2.example.com). Set scheduler tags so each list is handled by a single agent to avoid collisions.

4. Rollbacks

openclaw deploy --agent outbound-bot --sha 3b9c1f7

Instant rolls back to the previous commit if you pushed a broken workflow.

Next step: hit send responsibly

Deploy the stack on ClawCloud, queue a small CSV, and monitor replies before you scale. Outbound still works when it feels personal—OpenClaw just saves you from copy-pasting the boring parts. Ship carefully, respect inboxes, and close a few deals.