Connect Your AI Sales Agent to Any CRM

HubSpot, Salesforce, Airtable integration with code examples and automation workflows

⏱ 15 min read💻 Code included📅 Updated Feb 2026

Your AI sales agent is only as powerful as the systems it can access. CRM integration transforms your agent from a chatbot into a revenue-driving automation engine that qualifies leads, updates deal stages, creates tasks, and keeps your pipeline current — all without manual data entry.

This guide covers how to connect OpenClaw AI agents to the most popular CRM systems: HubSpot, Salesforce, Pipedrive, and Airtable. You'll get working code examples, webhook configurations, and automation workflows you can deploy today.

Why CRM Integration Matters

Without CRM integration, your sales agent is just answering questions. With it, your agent becomes a full sales assistant that:

Companies using AI agents with CRM integration report 40% reduction in admin time and 25% faster deal cycles.

Integration Architecture Overview

OpenClaw agents connect to CRMs through three methods:

  1. Direct API integration — Agent calls CRM APIs directly using tools you configure (best for HubSpot, Salesforce, Pipedrive)
  2. Webhook triggers — CRM sends events to your agent (new lead, deal stage change) and agent responds automatically
  3. No-code platforms — Use Zapier or n8n as middleware for CRMs without good APIs or complex workflows

We'll cover all three approaches with examples.

Method 1: HubSpot Integration (Direct API)

HubSpot has the most developer-friendly API. Integration takes 15-30 minutes.

Step 1: Get HubSpot API Key

  1. Log into HubSpot → Settings → Integrations → Private Apps
  2. Create new private app: "OpenClaw Sales Agent"
  3. Grant scopes: crm.objects.contacts.read, crm.objects.contacts.write, crm.objects.deals.read, crm.objects.deals.write
  4. Copy the API key (starts with pat-na1-...)

Step 2: Configure OpenClaw Tool

Create tools/hubspot.js in your OpenClaw workspace:

// tools/hubspot.js
const HUBSPOT_API_KEY = process.env.HUBSPOT_API_KEY;
const BASE_URL = 'https://api.hubapi.com';

async function createContact(email, firstName, lastName, company) {
  const response = await fetch(`${BASE_URL}/crm/v3/objects/contacts`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${HUBSPOT_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      properties: {
        email,
        firstname: firstName,
        lastname: lastName,
        company
      }
    })
  });
  return response.json();
}

async function updateDealStage(dealId, stage) {
  const response = await fetch(`${BASE_URL}/crm/v3/objects/deals/${dealId}`, {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${HUBSPOT_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      properties: { dealstage: stage }
    })
  });
  return response.json();
}

async function searchContact(email) {
  const response = await fetch(`${BASE_URL}/crm/v3/objects/contacts/search`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${HUBSPOT_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      filterGroups: [{
        filters: [{ propertyName: 'email', operator: 'EQ', value: email }]
      }]
    })
  });
  return response.json();
}

module.exports = { createContact, updateDealStage, searchContact };

Step 3: Add to AGENTS.md

Tell your agent how to use the HubSpot tool:

# AGENTS.md

## CRM Integration Rules

### Before Every Response
1. Search HubSpot for contact by email
2. If found, read their deal history and notes
3. Personalize response based on their stage

### After Qualification
1. If contact doesn't exist, create it
2. Create deal with stage "qualified"
3. Add conversation summary to contact notes
4. If hot lead (score 4/4), create task for sales rep

### Deal Stage Updates
- Prospect says "interested in demo" → move to "demo scheduled"
- Prospect says "need to discuss with team" → move to "decision maker buy-in"
- Prospect says "not right now" → move to "nurture"

Step 4: Test Integration

Message your agent: "I'm interested in your product. My email is [email protected]"

Check HubSpot — you should see a new contact created with conversation notes.

💡 Pro tip: Use HubSpot workflows to trigger agent actions. Example: When deal stage changes to "demo completed", HubSpot webhook notifies agent to send follow-up email with pricing.

Method 2: Salesforce Integration (OAuth + API)

Salesforce integration is more complex due to OAuth authentication, but it's the most powerful for enterprise sales teams.

Step 1: Create Connected App

  1. Salesforce Setup → App Manager → New Connected App
  2. Enable OAuth Settings
  3. Callback URL: https://your-openclaw-server.com/oauth/salesforce/callback
  4. Scopes: api, refresh_token, offline_access
  5. Save and copy Consumer Key + Consumer Secret

Step 2: OAuth Flow

Salesforce requires OAuth2 authentication. Create tools/salesforce-auth.js:

// tools/salesforce-auth.js
const CLIENT_ID = process.env.SALESFORCE_CLIENT_ID;
const CLIENT_SECRET = process.env.SALESFORCE_CLIENT_SECRET;
const REDIRECT_URI = process.env.SALESFORCE_REDIRECT_URI;

async function getAccessToken(authCode) {
  const response = await fetch('https://login.salesforce.com/services/oauth2/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code: authCode,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      redirect_uri: REDIRECT_URI
    })
  });
  return response.json();
}

async function refreshAccessToken(refreshToken) {
  const response = await fetch('https://login.salesforce.com/services/oauth2/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: refreshToken,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET
    })
  });
  return response.json();
}

module.exports = { getAccessToken, refreshAccessToken };

Step 3: Salesforce API Operations

Create tools/salesforce.js:

// tools/salesforce.js
const { refreshAccessToken } = require('./salesforce-auth');

let accessToken = process.env.SALESFORCE_ACCESS_TOKEN;
let instanceUrl = process.env.SALESFORCE_INSTANCE_URL;

async function createLead(email, firstName, lastName, company) {
  const response = await fetch(`${instanceUrl}/services/data/v59.0/sobjects/Lead`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      Email: email,
      FirstName: firstName,
      LastName: lastName,
      Company: company,
      LeadSource: 'AI Agent'
    })
  });
  
  if (response.status === 401) {
    // Token expired, refresh and retry
    const tokens = await refreshAccessToken(process.env.SALESFORCE_REFRESH_TOKEN);
    accessToken = tokens.access_token;
    return createLead(email, firstName, lastName, company);
  }
  
  return response.json();
}

async function updateOpportunity(oppId, stage) {
  const response = await fetch(`${instanceUrl}/services/data/v59.0/sobjects/Opportunity/${oppId}`, {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ StageName: stage })
  });
  return response.json();
}

module.exports = { createLead, updateOpportunity };

Salesforce integration is production-ready but requires more setup. For detailed OAuth flow implementation, see the OpenClaw + Salesforce guide.

Method 3: Airtable Integration (Simple API)

Airtable is perfect for startups and small teams. Integration takes 10 minutes.

Step 1: Get Airtable API Key

  1. Airtable Account → Create personal access token
  2. Grant scopes: data.records:read, data.records:write
  3. Select your base (e.g., "Sales CRM")
  4. Copy token and base ID

Step 2: Configure Tool

// tools/airtable.js
const AIRTABLE_TOKEN = process.env.AIRTABLE_TOKEN;
const BASE_ID = process.env.AIRTABLE_BASE_ID;
const TABLE_NAME = 'Leads';

async function createLead(email, name, company, status) {
  const response = await fetch(`https://api.airtable.com/v0/${BASE_ID}/${TABLE_NAME}`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${AIRTABLE_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      fields: {
        Email: email,
        Name: name,
        Company: company,
        Status: status,
        Source: 'AI Agent',
        'Created Date': new Date().toISOString()
      }
    })
  });
  return response.json();
}

async function updateLeadStatus(recordId, status) {
  const response = await fetch(`https://api.airtable.com/v0/${BASE_ID}/${TABLE_NAME}/${recordId}`, {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${AIRTABLE_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      fields: { Status: status }
    })
  });
  return response.json();
}

module.exports = { createLead, updateLeadStatus };

For complete Airtable automation workflows, see OpenClaw + Airtable integration guide.

Method 4: No-Code Integration (Zapier/n8n)

If your CRM doesn't have a good API or you want visual workflow building, use Zapier or n8n.

Zapier Integration

  1. Create Zap: "Webhook by Zapier" (trigger) → "CRM" (action)
  2. Copy webhook URL
  3. Configure OpenClaw to send lead data to webhook when qualified
  4. Zapier creates contact/deal in your CRM automatically

n8n Integration (Self-Hosted)

n8n is open-source and runs on your server (better for data privacy):

  1. Install n8n: npx n8n
  2. Create workflow: Webhook → HTTP Request (to OpenClaw) → CRM node
  3. Bi-directional sync: CRM updates trigger agent actions

n8n is ideal for complex workflows like: "When deal closes in CRM → agent sends onboarding email → creates tasks in project management tool".

Advanced: Bi-Directional Sync

Most integrations are one-way (agent → CRM). For true automation, set up bi-directional sync:

CRM → Agent Triggers

Configure CRM webhooks to notify your agent when:

Example: HubSpot Webhook

// server.js - Webhook endpoint
app.post('/webhooks/hubspot', async (req, res) => {
  const event = req.body[0]; // HubSpot sends array
  
  if (event.subscriptionType === 'deal.propertyChange') {
    const dealId = event.objectId;
    const newStage = event.propertyValue;
    
    // Notify agent
    await agent.handleCRMEvent({
      type: 'deal_stage_change',
      dealId,
      newStage
    });
  }
  
  res.status(200).send('OK');
});

Security Best Practices

CRM integration means your agent has access to sensitive customer data. Follow these security rules:

Common Integration Patterns

Pattern 1: Lead Qualification Pipeline

1. Prospect messages agent
2. Agent qualifies using BANT framework
3. If qualified → create contact + deal in CRM
4. If hot lead → create task for sales rep + send Slack notification
5. If cold lead → add to nurture campaign

Pattern 2: Deal Stage Automation

1. Agent detects buying signal ("ready to see pricing")
2. Agent updates deal stage to "proposal"
3. Agent generates custom proposal from template
4. Agent sends proposal via email
5. Agent schedules follow-up for 3 days later

Pattern 3: Pipeline Reporting

1. Every Monday 9am, agent queries CRM
2. Agent generates report: new leads, deals closed, pipeline value
3. Agent sends report to Slack #sales channel
4. Agent highlights deals at risk (no activity in 7+ days)

Troubleshooting Common Issues

Issue: "401 Unauthorized" Errors

Cause: API key expired or invalid scopes

Fix: Regenerate API key, verify scopes match what your code requests

Issue: Duplicate Contacts Created

Cause: Agent not checking if contact exists before creating

Fix: Always search by email first, only create if not found

Issue: Rate Limit Errors

Cause: Too many API calls in short time

Fix: Implement exponential backoff, batch operations, cache CRM data locally

Issue: Webhook Not Triggering

Cause: Firewall blocking incoming requests or wrong URL

Fix: Verify webhook URL is publicly accessible, check CRM webhook logs

Frequently Asked Questions

Which CRM systems work with OpenClaw?

OpenClaw integrates with any CRM that has an API: HubSpot, Salesforce, Pipedrive, Zoho, Airtable, and more. You can also use Zapier or n8n for no-code integrations with 1000+ CRMs.

Do I need coding skills to set up CRM integration?

Basic integrations (read/write contacts, update deals) require minimal coding — mostly copy-paste configuration. Complex workflows may need JavaScript knowledge or a no-code tool like Zapier.

How long does CRM integration take?

HubSpot and Airtable: 15-30 minutes. Salesforce: 30-60 minutes (more complex auth). Custom CRMs: 1-3 hours depending on API documentation quality.

Is my CRM data secure with AI agent access?

Yes. OpenClaw runs on your server, API keys are stored locally, and you control exactly which CRM operations the agent can perform through permission scopes. Your data never leaves your infrastructure.

Can I integrate multiple CRMs?

Yes. You can configure tools for multiple CRMs and the agent will use the appropriate one based on context. Example: HubSpot for marketing leads, Salesforce for enterprise deals.

Next Steps

CRM integration transforms your AI sales agent from a chatbot into a revenue-driving automation engine. Start with one CRM (HubSpot is easiest), get basic read/write working, then progressively add more sophisticated workflows.

Once your CRM integration is live, explore:

🚀 Ready to Automate Your Sales Pipeline?

Get 100 ready-to-use SOUL.md templates including CRM-integrated sales agents — only $9.90

Get SOUL.md Mega Pack →