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.1on 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.completedJSON 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.